Skip to content

Latest commit

 

History

History
90 lines (68 loc) · 3.18 KB

USAGE.md

File metadata and controls

90 lines (68 loc) · 3.18 KB

Usage Guide

The easy way

The easist way to use these packages is by creating a project with Briefcase <https://github.com/beeware/briefcase>__. Briefcase will download pre-compiled versions of these support packages, and add them to an Xcode project (or pre-build stub application, in the case of macOS).

The manual way

NOTE Briefcase usage is the officially supported approach for using this support package. If you are experiencing diffculties, one approach for debugging is to generate a "Hello World" project with Briefcase, and compare the project that Briefcase has generated with your own project.

The Python support package can be manually added to any Xcode project; however, you'll need to perform some steps manually (essentially reproducing what Briefcase is doing). The steps required are documented in the CPython usage guides:

For tvOS and watchOS, you should be able to broadly follow the instructions in the iOS guide.

Accessing the Python runtime

There are 2 ways to access the Python runtime in your project code.

Embedded C API.

You can use the Python Embedded C API to instantiate a Python interpreter. This is the approach taken by Briefcase; you may find the bootstrap mainline code generated by Briefcase a helpful guide to what is needed to start an interpreter and run Python code.

PythonKit

An alternate approach is to use PythonKit. PythonKit is a package that provides a Swift API to running Python code.

To use PythonKit in your project:

  1. Add PythonKit to your project using the Swift Package manager. See the PythonKit documentation for details.

  2. Create a file called module.modulemap inside Python.xcframework/macos-arm64_x86_64/Headers/, containing the following code:

module Python {
    umbrella header "Python.h"
    export *
    link "Python"
}
  1. In your Swift code, initialize the Python runtime. This should generally be done as early as possible in the application's lifecycle, but definitely needs to be done before you invoke Python code:
import Python

guard let stdLibPath = Bundle.main.path(forResource: "python-stdlib", ofType: nil) else { return }
guard let libDynloadPath = Bundle.main.path(forResource: "python-stdlib/lib-dynload", ofType: nil) else { return }
setenv("PYTHONHOME", stdLibPath, 1)
setenv("PYTHONPATH", "\(stdLibPath):\(libDynloadPath)", 1)
Py_Initialize()
// we now have a Python interpreter ready to be used
  1. Invoke Python code in your app. For example:
import PythonKit

let sys = Python.import("sys")
print("Python Version: \(sys.version_info.major).\(sys.version_info.minor)")
print("Python Encoding: \(sys.getdefaultencoding().upper())")
print("Python Path: \(sys.path)")

_ = Python.import("math") // verifies `lib-dynload` is found and signed successfully

To integrate 3rd party python code and dependencies, you will need to make sure PYTHONPATH contains their paths; once this has been done, you can run Python.import("<lib name>"). to import that module from inside swift.