When I was working on a Swift client project where we needed to call Python code directly from Xcode specifically using spaCy
for natural language processing I decided to integrate PythonKit. Everything seemed fine during setup until I hit this wall:
“Python library not found. Set the PYTHON_LIBRARY environment variable with the path to a Python library.”
This blog post walks you through exactly what went wrong, how I fixed it, and how I improved the integration with real-time interactive Swift functionality using PythonKit.
I Was Using PythonKit
I was tasked with a feature where Swift needed to analyze text using spaCy’s NLP models. Instead of writing a web API wrapper around Python, I used PythonKit to call Python directly from Swift code inside an Xcode project.
Here’s what I did:
- Installed PythonKit using Homebrew
- Imported PythonKit into the project
- Built the project successfully
But once I ran the app, Swift crashed immediately with this runtime error.
The Error I Got
Python library not found. Set the PYTHON_LIBRARY environment variable with the path to a Python library.
Even though Python was installed and working perfectly in my terminal, PythonKit couldn’t locate the shared library (libpythonX.Y.dylib
) it needed at runtime. That’s because Swift doesn’t use the terminal’s environment unless explicitly told to.
PythonKit Looks For
When PythonKit initializes, it tries to dynamically load the following:
libpython3.7.dylib (or similar)
A typical path on my system looked like this:
/usr/local/opt/python@3.7/Frameworks/Python.framework/Versions/3.7/lib/libpython3.7.dylib
But if this isn’t properly linked, or if the environment variable isn’t set, Swift just fails.
How I Fix It
I Located the Python Dynamic Library
I opened Terminal and ran:
/usr/local -name "libpython*.dylib"
In my case, it returned:
/usr/local/Cellar/python@3.7/3.7.6_1/Frameworks/Python.framework/Versions/3.7/lib/libpython3.7.dylib
I Set the PYTHON_LIBRARY
Variable
Next, I exported this path:
PYTHON_LIBRARY="/usr/local/Cellar/python@3.7/3.7.6_1/Frameworks/Python.framework/Versions/3.7/lib/libpython3.7.dylib"
To make it permanent for Terminal use, I added it to my ~/.zshrc
. But for Xcode, I had to manually go into:
Product > Scheme > Edit Scheme > Environment Variables
And add:
- Name:
PYTHON_LIBRARY
- Value: (path to your .dylib)
That was the turning point. The app no longer crashed.
Working Swift Code Using PythonKit
Here’s a minimal working example that integrates spaCy with Swift using PythonKit:
PythonKit
let sys = Python.import("sys")
print("Python version:", sys.version)
let spacy = Python.import("spacy")
let nlp = spacy.load("en_core_web_sm")
let doc = nlp("Swift and Python are working together!")
for token in doc {
print(token.text, token.pos_)
}
This verified my Python environment and spaCy model were accessible from Swift. But I wanted more.
Added Practice Functionality
To make the integration more interactive, I added a custom text analysis function:
analyze(text: String) {
let nlp = Python.import("spacy").load("en_core_web_sm")
let doc = nlp(text)
print("\nTokens and POS Tags:")
for token in doc {
print("\(token.text) - \(token.pos_)")
}
print("\nNamed Entities:")
for ent in doc.ents {
print("\(ent.text) - \(ent.label_)")
}
}
print("Enter your text:")
if let input = readLine() {
analyze(text: input)
}
Sample Output
your text:
Barack Obama was born in Hawaii.
Tokens and POS Tags:
Barack - PROPN
Obama - PROPN
was - AUX
born - VERB
in - ADP
Hawaii - PROPN
. - PUNCT
Named Entities:
Barack Obama - PERSON
Hawaii - GPE
It turned my Swift terminal into a mini-NLP tool using Python in the backend.
Still Not Working? Here’s What I Tried
If the .dylib
is still not found:
- Reinstall Python properly via Homebrew:
reinstall python@3.7
brew link --overwrite --force python@3.7
- Or switch to Python 3.10 if you’re using newer versions like 3.12 (which often skip building
libpython.dylib
by default):
install python@3.10
You’ll still need to export the PYTHON_LIBRARY
variable accordingly.
Final Thought
This error taught me how environment variables, dynamic libraries, and language bridges (Swift ↔ Python) work under the hood. It’s not enough to just install Python you need to make sure your Swift app knows exactly where to find the Python runtime library at runtime.
Using spaCy
with Swift via PythonKit turned out to be a powerful combo. The real-time NLP processing inside a native Swift environment gave me the best of both worlds.