SwiftUI – packing with Python and a module library

Question:

My goal: Import via PythonKit Python 3.9.1 in my Swift Project, where I can use it to package it with the needed module "openpyxl" (for filling an excel sheet with values).

Here are the imports at the beginning of the specific python file:

# some imports
import sys
from openpyxl import load_workbook # Library for editing xlsx-files
import datetime # for current date-informations
import csv # for reading csv

As you read I need Python 3 and the most Macs haven’t installed it. So I want to include it in my App. I am new to Swift and have no clue how to achieve this.

What I have done so far:

  • Added the Swift Package Depency for "PythonKit" (used the Github Link and chose "master" branch)
  • Browsing Google for how to include a specific Python version in swift projects (and use them to execute Python files)
  • Asked Google how to add a library like "openpyxl" to PythonKit/Swift

Can you take me further? I am grateful for any tips how to get these python thing work in my Swift App. Would be wonderful to integrate the python library and make it work on every machine.

Asked By: allxrob

||

Answers:

Found a solution:

Create a Python .plugin bundle with py2app, load it into Xcode and work with the path of the python binary.

This is the setup.py you could use:

"""
This is a setup.py script to create a py2app plugin bundle
Usage:
    python setup.py py2app
"""

from setuptools import setup


APP = ['RandomFile.py']
OPTIONS = {
  # Any local packages to include in the bundle should go here.
  # See the py2app documentation for more.
  "includes": [], 
}

setup(
    plugin=APP,
    options={'py2app': OPTIONS},
    setup_requires=['py2app'],
    install_requires=['openpyxl'],
)

The documentation for building with py2app you can find here: https://py2app.readthedocs.io/en/latest/index.html

After building the plugin, we can drag it into our Xcode Project and get the path of it in Swift like this:

let pluginPath = Bundle.main.path(forResource: "Bridge", ofType: "plugin")
Answered By: allxrob