GitHub Actions Artifact Client for Python
Project description
gha-artifact-client
Python wrapper/CLI around @actions/artifact for creating workflow artifacts
from inside a GitHub Actions job.
Allows you to upload workflow artifacts dynamically from Python code without
needing to invoke the actions/upload-artifact action in your workflow yaml.
Notes
- Uploading artifacts only works during the lifetime of a GitHub Actions job.
- Unlike other GitHub API interactions requires a
ACTIONS_RUNTIME_TOKENand and not aGITHUB_TOKEN. - Since the upload API is not publicly documented, this package vendors a custom-built node wrapper around the official @actions/artifact package, which is invoked with node. node needs to be provided by the user.
- Only depends on the Python standard library.
- Only direct single-file uploads are supported. If you need zip files, you need to create them yourself before uploading.
Usage
Python API
import io
from gha_artifact_client import ArtifactClientApi
# Credentials from environment variables (default)
api = ArtifactClientApi()
# Or supply credentials explicitly — useful when you don't want them
# sitting in os.environ where other subprocesses could inherit them
api = ArtifactClientApi(
runtime_token="...",
results_url="...",
)
# Upload a file from disk
result = api.upload_artifact("dist/package.tar.gz")
# Upload with a custom artifact name and expiry time
result = api.upload_artifact(
"dist/package.tar.gz",
name="build-output.tar.gz",
expires_in=7 * 24 * 3600, # 7 days from now, in seconds
)
# Or set an exact expiry datetime (must be timezone-aware)
import datetime as dt
result = api.upload_artifact(
"dist/package.tar.gz",
expires_at=dt.datetime(2026, 12, 31, 23, 59, 59, tzinfo=dt.timezone.utc),
)
print(result.id)
print(result.digest)
# Upload from in-memory bytes
result = api.upload_artifact_bytes(
b"hello from memory\n",
name="build-output.txt",
)
print(result.id)
# Upload using a file-like object
with open("dist/package.tar.gz", "rb") as f:
result = api.upload_artifact_fileobj(f, name="package.tar.gz")
print(result.id)
CLI
gha-artifact-client upload dist/package.tar.gz --name package.tar.gz --expires-in 604800
--expires-in takes seconds (int or float). Use --expires-at for an exact
point in time as a timezone-aware ISO 8601 datetime. The two flags are mutually
exclusive.
Credentials default to ACTIONS_RUNTIME_TOKEN and ACTIONS_RESULTS_URL from
the environment, but can be supplied explicitly:
gha-artifact-client --runtime-token "$MY_TOKEN" --results-url "$MY_RESULTS_URL" \
upload dist/package.tar.gz
Credentials & Security Considerations
Uploading artifacts requires a URL and a credential that is only available inside a live GitHub Actions job:
ACTIONS_RUNTIME_TOKEN— a token created for the current job.ACTIONS_RESULTS_URL— the endpoint for the artifact storage backend.
These are not the same as GITHUB_TOKEN and are not exposed as regular
environment variables. They are only exposed to action steps and not run
steps. To make them available in run steps you can extract them via
actions/github-script:
permissions: {}
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Get artifact upload credentials
id: vars
uses: actions/github-script@v8
with:
script: |
core.setOutput('ACTIONS_RUNTIME_TOKEN', process.env['ACTIONS_RUNTIME_TOKEN'])
core.setOutput('ACTIONS_RESULTS_URL', process.env['ACTIONS_RESULTS_URL'])
- name: Upload artifact
env:
ACTIONS_RUNTIME_TOKEN: ${{ steps.vars.outputs.ACTIONS_RUNTIME_TOKEN }}
ACTIONS_RESULTS_URL: ${{ steps.vars.outputs.ACTIONS_RESULTS_URL }}
run: python your_script.py
Notes on the Token and Security
-
The token is valid for
timeout-minutesof the current job, which defaults to 360 minutes (6 hours). After that, it expires and cannot be used to upload artifacts. -
Even if the token hasn't expired, it appears to be invalidated after the job completes. Using it after the current job completes results in:
Failed to CreateArtifact: Received non-retryable error: Failed request: (403) Forbidden: job is complete
-
From what I understand, the token can also be used to upload cache entries and job logs, but I haven't tested that. If you are passing them to third party code, consider the security implications of that. I'd recommend to remove the token from the environment when calling third-party code that doesn't need it, to avoid accidental leaks.
-
ACTIONS_RESULTS_URLfor github.com on hosted runners, at the time of writing, ishttps://results-receiver.actions.githubusercontent.com/.
Development
- Install Python dependencies with
uv sync. - Install node wrapper dependencies with
npm ciinnode-wrapper/. - Lint the node wrapper with
npm run lintinnode-wrapper/. - Type-check the node wrapper with
npm run tscinnode-wrapper/. - Rebuild the vendored node wrapper with
npm run buildinnode-wrapper/.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file gha_artifact_client-0.1.0.tar.gz.
File metadata
- Download URL: gha_artifact_client-0.1.0.tar.gz
- Upload date:
- Size: 311.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.11.0 {"installer":{"name":"uv","version":"0.11.0","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"26.04","id":"resolute","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c0073122ac9720afe929c37de6ca85939e6ea44fa2b704e1abbba426032ffafa
|
|
| MD5 |
5bf9f2e6b52327108ab222043577f6db
|
|
| BLAKE2b-256 |
aff4967dc900fca4aced8743cc4a704a044448c52ed6cca36d02f78a9554f2f1
|
File details
Details for the file gha_artifact_client-0.1.0-py3-none-any.whl.
File metadata
- Download URL: gha_artifact_client-0.1.0-py3-none-any.whl
- Upload date:
- Size: 246.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.11.0 {"installer":{"name":"uv","version":"0.11.0","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"26.04","id":"resolute","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
afb6cf2418beb7f75a91e0cd606f756372bc6429543efd70b2c45a3c089c8713
|
|
| MD5 |
33aeb1af15672889ea0927511511431d
|
|
| BLAKE2b-256 |
ff561ef9fd81aee2f822d7d850cb245327131b2ed253edeb91855c5d638606da
|