Skip to content

Commit

Permalink
Add python publishing to CI
Browse files Browse the repository at this point in the history
  • Loading branch information
0xOmarA committed Sep 19, 2023
1 parent 72f52d8 commit e637c3c
Show file tree
Hide file tree
Showing 3 changed files with 160 additions and 0 deletions.
69 changes: 69 additions & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -448,3 +448,72 @@ jobs:
- name: Publish Packages
working-directory: interop/csharp/
run: dotnet nuget push RadixDlt.RadixEngineToolkit.*.nupkg --source https://api.nuget.org/v3/index.json --api-key ${{ secrets.NUGET_ORG_API_KEY }}
publish-python-package:
needs: [build, generate-uniffi-bindings]
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Fetch secrets
uses: radixdlt/public-iac-resuable-artifacts/fetch-secrets@main
with:
role_name: ${{ secrets.PYPI_SECRET_ROLE_NAME }}
app_name: 'radix-engine-toolkit'
step_name: 'pypi-credentials'
secret_prefix: 'PYPI'
secret_name: ${{ secrets.PYPI_SECRET_NAME }}
parse_json: true
- name: Install Dependencies
run: python3 -m pip install black build twine
- uses: actions/download-artifact@v3
with:
path: artifacts
- name: Set up Python 3.11
uses: actions/setup-python@v4
with:
python-version: 3.11
- name: Copy bindings
run: |
mkdir ./interop/python/radix_engine_toolkit
cp \
./artifacts/uniffi-bindings/radix_engine_toolkit_uniffi.py \
./interop/python/radix_engine_toolkit/__init__.py
- name: Dynamic Library Script replacement
run: |
python3 ./interop/python/replacement.py ./interop/python/radix_engine_toolkit/__init__.py
rm ./interop/python/replacement.py
- name: Stubs generation
run: |
stubgen \
./interop/python/radix_engine_toolkit/__init__.py \
--output ./interop/python/
- name: Code Formatting
run: |
python3 -m black ./interop/python/
- name: Copy Dynamic Libraries
run: |
for TARGET_TRIPLE in "aarch64-apple-darwin" "x86_64-apple-darwin" "aarch64-unknown-linux-gnu" "x86_64-unknown-linux-gnu" "x86_64-pc-windows-gnu"
do
for FILE_NAME in "libradix_engine_toolkit_uniffi.so" "libradix_engine_toolkit_uniffi.dylib" "radix_engine_toolkit_uniffi.dll"
do
cp \
./artifacts/radix-engine-toolkit-uniffi-$TARGET_TRIPLE/$FILE_NAME \
./interop/python/radix_engine_toolkit/$TARGET_TRIPLE \
2>/dev/null
done
done
- name: Build Package
working-directory: ./interop/python/
run: |
python3 -m build
- name: Check Builds
working-directory: ./interop/python/
run: |
python3 -m twine check dist/*
- name: Publish
working-directory: ./interop/python/
run: |
python3 -m twine upload -u ${{ env.PYPI_USERNAME }} -p ${{ env.PYPI_PASSWORD }} dist/*
62 changes: 62 additions & 0 deletions interop/python/replacement.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import platform
import ctypes
import sys
import os
import re

def _uniffi_load_indirect() -> ctypes.CDLL:
"""
This is how we find and load the dynamic library provided by the component.
The dynamic library is assumed to exist right beside the code and it's name if the same as the
target triple.
Currently, the supported architectures are:
* x86-64 and Arm64 Apple Darwin
* x86-64 and Arm64 Linux GNU
* x86-64 Win64
"""

def library_file_name() -> str:
is_x86: bool = platform.machine() in ("AMD64", "x86_64")
is_arm: bool = platform.machine() == "arm64"
system: str = platform.system()

if is_x86 and system == "Darwin":
return "x86_64-apple-darwin"
elif is_arm and system == "Darwin":
return "aarch64-apple-darwin"
elif is_x86 and system == "Linux":
return "x86_64-unknown-linux-gnu"
elif is_arm and system == "Linux":
return "aarch64-unknown-linux-gnu"
elif is_x86 and system == "Windows":
return "x86_64-pc-windows-gnu"
else:
raise NotImplemented(f"No implementation of the Radix Engine Toolkit is available on your platform. Information detected: is_x86: {is_x86}, is_arm: {is_arm}, os: {system}")

file_name: str = library_file_name()
path: str = os.path.join(os.path.dirname(__file__), file_name)
return ctypes.cdll.LoadLibrary(path)

def main() -> None:
# The first arg is the path of the file which we want to do the replacement for.
path: str = sys.argv[1]

# The regex expression used to read this function
regex: str = r'(def _uniffi_load_indirect\(\)\s*(->\s*.*)?:[\d\w\s\n:{}.\[\]=\(\)#,$`\'\"\-*\/><]*^$)'

# Open THIS file and read the function definition through the regex expression.
with open(os.path.abspath(__file__), 'r') as file:
new_func_def: str = re.findall(regex, file.read(), re.MULTILINE)[0][0]

# Open the replacement file, read it, apply regex replacement to it, and then write it again.
with open(path, 'r') as file:
content: str = file.read()
old_func_def: str = re.findall(regex, content, re.MULTILINE)[0][0]

new_content: str = content.replace(old_func_def, new_func_def)
with open(path, 'w') as file:
file.write(new_content)

if __name__ == "__main__":
main()
29 changes: 29 additions & 0 deletions interop/python/setup.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import setuptools

setuptools.setup(
name="radix-engine-toolkit",
version="0.12.1",
packages=["radix_engine_toolkit"],
author="radixdlt",
description="A Python wrapper around the Radix Engine Toolkit that provides Radix Ledger primitives to Python.",
long_description="Long Description",
long_description_content_type="text/markdown",
license='Apache-2.0',
python_requires='>=3.6',
install_requires=[],
url="https://github.com/radixdlt/radix-engine-toolkit",
project_urls={
"Bug Tracker": "https://github.com/radixdlt/radix-engine-toolkit/issues",
},
classifiers=[
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.7",
"Programming Language :: Python :: 3.8",
"Programming Language :: Python :: 3.9",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
"Natural Language :: English",
"Operating System :: OS Independent",
"License :: OSI Approved :: MIT License",
],
)

0 comments on commit e637c3c

Please sign in to comment.