PyObjC Framework SearchKit

12.1 · active · verified Tue Apr 14

PyObjC is a bridge between Python and Objective-C, enabling Python scripts to interact with and extend existing Objective-C class libraries, most notably Apple's Cocoa frameworks on macOS. The `pyobjc-framework-searchkit` package provides Python wrappers specifically for the macOS SearchKit framework, allowing for programmatic creation, management, and searching of full-text indexes. The PyObjC library (which includes this framework wrapper) is actively maintained, with version 12.1 released on 2025-11-14, and generally aligns its releases with new macOS SDK versions and Python language support changes.

Warnings

Install

Imports

Quickstart

This quickstart demonstrates how to create a basic SearchKit index in a temporary directory, add text documents, and then perform a simple query to retrieve matching documents and their relevance scores. It highlights the use of `NSURL` for path handling, the `alloc().init...` pattern for object instantiation, and basic `SKIndex` and `SKSearch` operations. Ensure you have the `Foundation` framework available (it's part of `pyobjc-framework-cocoa` or the `pyobjc` meta-package).

import os
import tempfile
import shutil
from Foundation import NSURL
from SearchKit import SKIndex, SKDocument, SKSearch, SKSearchGroup, kSKSearchOptionFindSimilar, kSKSearchOptionNone

# Create a temporary directory for the index
temp_dir = tempfile.mkdtemp()
index_path = os.path.join(temp_dir, "MySearchIndex")

print(f"Creating SearchKit index at: {index_path}")

# 1. Create an SKIndex
# Convert Python path to NSURL
index_url = NSURL.fileURLWithPath_(index_path)

# Create a new index (kSKIndexTypeInverted or kSKIndexTypeVector)
# For simplicity, using kSKIndexTypeInverted here
index = SKIndex.alloc().initForURL_create_dictionary_(
    index_url,
    True,
    None # No special options dictionary
)

if not index:
    print("Failed to create SearchKit index.")
    shutil.rmtree(temp_dir)
    exit()

# 2. Add documents to the index
doc_id_counter = 0
def add_document(content, filename):
    global doc_id_counter
    doc_id_counter += 1
    doc_name = f"doc_{doc_id_counter}"
    # Create an SKDocument from content string
    document = SKDocument.alloc().initWithURL_mimeType_textEncoding_(
        NSURL.fileURLWithPath_(filename), # URL identifies the document, can be dummy
        None, # MIME type, can be None
        None  # Text encoding, can be None
    )
    if document:
        index.addDocumentWithText_url_properties_(document, content, None, None)
        print(f"Added '{filename}' to index.")
    else:
        print(f"Failed to create SKDocument for {filename}")

add_document("The quick brown fox jumps over the lazy dog.", "file1.txt")
add_document("Lazy dogs often sleep deeply.", "file2.txt")
add_document("A quick jump is good exercise.", "file3.txt")

index.flush()
index.close()

# 3. Perform a search
search_index = SKIndex.alloc().initForURL_create_dictionary_(index_url, False, None)
if not search_index:
    print("Failed to open SearchKit index for searching.")
    shutil.rmtree(temp_dir)
    exit()

search_query = "quick dog"
print(f"\nSearching for: '{search_query}'")

search = SKSearch.alloc().initWithIndex_(
    search_index
)

if search:
    search_options = kSKSearchOptionNone
    search_group = SKSearchGroup.alloc().init()
    # You can specify the maximum number of results
    results = search.findMatchesForQuery_maxCount_(
        search_query,
        10 # Max 10 results
    )

    if results:
        for i, doc_ref in enumerate(results.objectAtIndex_(0)):
            score = results.objectAtIndex_(1)[i]
            # Get original document URL (which we used as a dummy path)
            doc_url = search_index.documentPropertiesForDocumentRef_(doc_ref).objectForKey_("kSKDocumentURL").path()
            print(f"  Match: {doc_url} (Score: {score:.2f})")
    else:
        print("  No matches found.")
else:
    print("Failed to create SKSearch object.")

search_index.close()

# 4. Clean up
shutil.rmtree(temp_dir)
print(f"\nCleaned up temporary index directory: {temp_dir}")

view raw JSON →