How to Fix a ‘Python Library Not Found’ Error with PythonKit

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.

Related blog posts