Using PythonKit in Xcode Playground and project

Hi, I'm trying using PythonKit in my Xcode project and Playground for data science with Swift instead of Jupyter Notebook.

I have some questions about PythonKit.

1. Specifying python path in my Xcode project and Playground

In my Xcode Playground, the version of Python is 3.9, but I'm using conda to install python 3.7 in my shell

# In my zsh shell
$ python --version
3.7.10
$ which python
python: aliased to /opt/miniconda3/bin/python3
// In Playground.swift
let sys = try Python.import("sys")

print("Python \(sys.version_info.major).\(sys.version_info.minor)")
print("Python Version: \(sys.version)")
print("Python Encoding: \(sys.getdefaultencoding().upper())")

// Python 3.9
// Python Version: 3.9.2 (default, Feb 24 2021, 13:26:09) 
// [Clang 12.0.0 (clang-1200.0.32.29)]
// Python Encoding: UTF-8

My questions:

  • Is that possible to specify python path in my Playground and Xcode project?
  • How do I ship my Swift App with Python and Python modules? It might be:
    • a macOS app
    • an iOS app
    • a pure swift executable running on Linux (maybe within a docker container).

2. How to draw matplotlib's plots in the Playground and macOS Apps

Is that possible to call matplotlib API and draw plots with Swift in a Xcode Playground or a macOS app? Is there any sample code or project to do that?

3. Data Science in Swift

Is there any recommended Swift package could be replaced/compatible with numpy, pandas, matplotlib, etc. when using PythonKit?


Any help would be appreciated.

I only know how to resolve your first question.

You can use PythonLibrary.useVersion to change the Python version. As PythonLibrary. enforceNonLoadedPythonLibrary indicates, you must call PythonKit.useVersion before loading any Python libraries.

It seems to search system python for use. How could I specify python installed by conda?

Hi @xareelee, quite interesting to see more data science interest in Swift! I encountered the same issue for some project I'm working on where I use PythonKit with Swift and Python is installed via Conda. Here's an internal note for the fix that I have been using so far in Xcode:

Note: add PYTHON_LIBRARY ENV variable to point to Conda Python in XCode for running/testing (From "Edit Scheme..."). Example /opt/miniconda3/envs/<yourenv>/lib/libpython3.8.dylib

2 Likes

Thanks for reply.

To make this work, you also need to set "App Sandbox" (key: com.apple.security.app-sandbox ) to "NO" in the .entitlement file while development, and this only works for the project, not for Xcode Playground.

  1. In my playground within the same project, the python version is still not my conda's Python. I still wonder how to achieve this in Xcode's Playground.

  2. Furthermore, how to archive this Xcode project into .app with the specific Python version and associated libs?

Interested if this was solved? I'm struggling with same problem, trying to bundle python into .app folder for swift project in xcode. Actually I manage so far

            let appFolder = Bundle.main.resourceURL?.path
            print(appFolder).  # debug
            print(ProcessInfo.processInfo.environment["PYTHON_LIBRARY"]). # debug
            PythonLibrary.useLibrary(at: appFolder! + "/python2/include/libpython3.9.dylib")
            PythonLibrary.useVersion(3, 9)

I have put my python file folder structure (bin, include, lib) generated by venv as asset to Xcode project.

The library seems to be found but it can not find modules:

Loading symbol 'Py_Initialize' from the Python library...

Trying to load library at '/Users/kayttaja/Library/Developer/Xcode/DerivedData/appi1-bodjqzsktzwjwkfsjlzuomlbviap/Build/Products/Debug/appi1.app/Contents/Resources/python2/include/libpython3.9.dylib'...

Library at '/Users/kayttaja/Library/Developer/Xcode/DerivedData/appi1-bodjqzsktzwjwkfsjlzuomlbviap/Build/Products/Debug/appi1.app/Contents/Resources/python2/include/libpython3.9.dylib' was sucessfully loaded.

Python path configuration:

PYTHONHOME = (not set)

PYTHONPATH = (not set)

program name = 'python3'

isolated = 0

environment = 1

user site = 1

import site = 1

sys._base_executable = '/Users/kayttaja/Library/Developer/Xcode/DerivedData/appi1-bodjqzsktzwjwkfsjlzuomlbviap/Build/Products/Debug/appi1.app/Contents/MacOS/appi1'

sys.base_prefix = '/usr/local/Cellar/python@3.9/3.9.9/Frameworks/Python.framework/Versions/3.9'

sys.base_exec_prefix = '/usr/local/Cellar/python@3.9/3.9.9/Frameworks/Python.framework/Versions/3.9'

sys.platlibdir = 'lib'

sys.executable = '/Users/kayttaja/Library/Developer/Xcode/DerivedData/appi1-bodjqzsktzwjwkfsjlzuomlbviap/Build/Products/Debug/appi1.app/Contents/MacOS/appi1'

sys.prefix = '/usr/local/Cellar/python@3.9/3.9.9/Frameworks/Python.framework/Versions/3.9'

sys.exec_prefix = '/usr/local/Cellar/python@3.9/3.9.9/Frameworks/Python.framework/Versions/3.9'

sys.path = [

'/usr/local/Cellar/python@3.9/3.9.9/Frameworks/Python.framework/Versions/3.9/lib/python39.zip',

'/usr/local/Cellar/python@3.9/3.9.9/Frameworks/Python.framework/Versions/3.9/lib/python3.9',

'/usr/local/Cellar/python@3.9/3.9.9/Frameworks/Python.framework/Versions/3.9/lib/python3.9/lib-dynload',

]

Fatal Python error: init_fs_encoding: failed to get the Python codec of the filesystem encoding

Python runtime state: core initialized

ModuleNotFoundError: No module named 'encodings'

Thanks for any help. I have tried to find clues for this now quite many evenings without any success.