From Swift Import Python
Build a macOS app to run Python scripts from your SwiftUI codebases
Python for long has established itself as the undisputed leader of data science. But as the size of data continues to increase, Python’s shortcomings are getting noticed. Slow speed, limitations in parallelism, and lack of type safety all act as a roadblock in large scale applications.
Google is clearly putting its bets on Swift as the future of deep learning. No wonder, they’ve heavily invested in Swift for Tensorflow.
While Python boasts of a huge collection of libraries and shifting away from it won’t be a cakewalk, but still we can leverage its interoperability with Swift.
Yes, you can run python code from Swift by using the PythonKit, a framework based on the Python
module from the Swift for TensorFlow project.
It’s important to note that Python is not available on iOS. But you can build pretty awesome utility apps for macOS and Linux.
Advantages of PythonKit
- Your Swift codebase gets direct access to the rich set of Python modules and packages.
- Python developers can easily build macOS apps to run automation scripts and perform numeric computations.
- Instead of bundling large OpenCV and Tensorflow frameworks in Swift, you can simply install the Python counterparts on your system and use it across all macOS applications that involve PythonKit.
In the next few sections, we’ll see how to setup PythonKit in a SwiftUI macOS application and perform a few interesting tasks.
Adding PythonKit in Your macOS Application
To get started create a new Xcode project with macOS as the target and add the following package dependency using Swift Package Manager:
.package(url: "https://github.com/pvieito/PythonKit.git", .branch("master")),
Now, you can import PythonKit
in your Swift views and get started. To check the current python version and update it use the following lines:
print(Python.version)
PythonLibrary.useVersion(2)
//or
PythonLibrary.useVersion(3, 8)
Note: PythonLibrary.useVersion
needs to be put just below the import statement. You cannot change Python version number dynamically at run-time.
Next, ensure that you’ve removed App sandbox from the “Signing and Capabilities” section, as we’ll run Python programs on our Mac directly.
Run Your First Python Script In Swift
Let’s write a hello world Esque Python function in a .py
file:
def hello():
return "Hello Swift, I'm Python"
Now, save this in a file and note down its path.
The following Swift method invokes the above Python function and gets the result back:
func runPythonCode(){
let sys \= Python.import("sys")
sys.path.append(dirPath)
let example \= Python.import("sample")
let response \= example.hello()
}
Few things to observe from the above piece of Swift code:
- The
dirPath
is the path to the file location. For me it is :/Users/anupamchugh/Desktop/workspace/
. Python.import
is used to import a Python module. In our case, we’re importing thesample.py
file which contained our hello world code.example
is a Swift instance of the type PythonObject. We’re invoking thehello
function over it.- The response instance is also a
PythonObject
which is implicitly converted into a string in our case.
We can explicitly convert PythonObject
into the native Swift types by wrapping them in the following ways:
let str \= String(pythonString)!
let arr \= Array(pythonArray)!
Swap Python Variables And Return To Swift
Let’s look at the classic case of interchanging the contents of two variables present in Swift in Python function:
def swap(a, b):
a, b = b, a
return a, b
Now, let’s call it from the Swift function to get back the results:
func swapNumbersInPython(){
let sys = Python.import("sys")
sys.path.append(dirPath)
let example = Python.import("sample")
let response = example.swap(swapA, swapB)
let arr : [Int] = Array(response)!
swapA = arr[0]
swapB = arr[1]
}
swapA
and swapB
are SwiftUI state variables, which will eventually be updated on the screen.
Let’s run our macOS SwiftUI application with the above Python script:
With that, we managed to build our first macOS application with Swift and Python interoperability.
But this was trivial. Let’s write a fancier Python script.
Download Videos Using Python Scripts And Show In SwiftUI VideoPlayer
Python has a popular package, named youtube-dl
for downloading videos from YouTube and many other websites.
Let’s install it on our mac. The following pip command is for Python3:
pip3 install youtube-dl
Now, add the following function in your Python file:
import youtube_dl
videoName = "NA"
def hello():
return "Hello Swift, this is Python"
def swap(a, b):
a, b = b, a
return a, b
def downloadVideo(link, path):
ydl_opts = {
'format': 'best',
'writesubtitles' : 'writesubtitles',
'outtmpl': path + '/%(title)s.%(ext)s'
}
with youtube_dl.YoutubeDL(ydl_opts) as ydl:
info_dict = ydl.extract_info(link, download=False)
videoName = info_dict.get('title', None) + '.' + info_dict.get('ext', None)
ydl.download([link])
return videoName
The link
and path
arguments are passed from Swift with the former being a video link and the latter being the directory path where the video would be saved.
ydl.download()
downloads the video and we return the videoName
back to the Swift code:
func downloadVideo(link: String){
let sys = Python.import("sys")
sys.path.append(dirPath)
let example = Python.import("sample")
let response = example.downloadVideo(link, dirPath)
videoPath = String(response)
}
Now, SwiftUI in WWDC 2020 introduced built-in support for VideoPlayer
on devices running macOS 11.0 and iOS 14. Still, for iOS 13, you can leverage the UIViewRepresentable
protocol to create a custom video view.
By using the videoPath
, we are able to display the downloaded video file in SwiftUI as shown below:
let url = URL(fileURLWithPath:dirPath+videoPath)
VideoPlayer(player: AVPlayer(url: url))
Let’s run the above mac application to see the output:
You can find the full source code of the SwiftUI application and Python script in the GitHub Repository.
Conclusion
We saw how Python-Swift interoperability makes it possible to run Python code from Swift. Besides video downloaders, you can also run automation tasks such as batch file renaming, disk space analyzer, and many more.
Python and Swift are two languages with clean and easy syntax. While the latter is getting groomed as the future of Deep Learning, the former would play a key role as the second fiddle in the years to come.
Update: July 2022: The launch of PyScript in PyCon 2022 has led to new ways of running Python from HTML. With Python and Swift already interoperable, the possibilities of using Python in mobile apps is limitless.