{"library":"pyobjc-framework-searchkit","title":"PyObjC Framework SearchKit","description":"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.","language":"python","status":"active","last_verified":"Sat May 16","install":{"commands":["pip install pyobjc-framework-searchkit","pip install pyobjc"],"cli":null},"imports":["from SearchKit import SKIndex, SKSearch","from Foundation import NSURL"],"auth":{"required":false,"env_vars":[]},"quickstart":{"code":"import os\nimport tempfile\nimport shutil\nfrom Foundation import NSURL\nfrom SearchKit import SKIndex, SKDocument, SKSearch, SKSearchGroup, kSKSearchOptionFindSimilar, kSKSearchOptionNone\n\n# Create a temporary directory for the index\ntemp_dir = tempfile.mkdtemp()\nindex_path = os.path.join(temp_dir, \"MySearchIndex\")\n\nprint(f\"Creating SearchKit index at: {index_path}\")\n\n# 1. Create an SKIndex\n# Convert Python path to NSURL\nindex_url = NSURL.fileURLWithPath_(index_path)\n\n# Create a new index (kSKIndexTypeInverted or kSKIndexTypeVector)\n# For simplicity, using kSKIndexTypeInverted here\nindex = SKIndex.alloc().initForURL_create_dictionary_(\n    index_url,\n    True,\n    None # No special options dictionary\n)\n\nif not index:\n    print(\"Failed to create SearchKit index.\")\n    shutil.rmtree(temp_dir)\n    exit()\n\n# 2. Add documents to the index\ndoc_id_counter = 0\ndef add_document(content, filename):\n    global doc_id_counter\n    doc_id_counter += 1\n    doc_name = f\"doc_{doc_id_counter}\"\n    # Create an SKDocument from content string\n    document = SKDocument.alloc().initWithURL_mimeType_textEncoding_(\n        NSURL.fileURLWithPath_(filename), # URL identifies the document, can be dummy\n        None, # MIME type, can be None\n        None  # Text encoding, can be None\n    )\n    if document:\n        index.addDocumentWithText_url_properties_(document, content, None, None)\n        print(f\"Added '{filename}' to index.\")\n    else:\n        print(f\"Failed to create SKDocument for {filename}\")\n\nadd_document(\"The quick brown fox jumps over the lazy dog.\", \"file1.txt\")\nadd_document(\"Lazy dogs often sleep deeply.\", \"file2.txt\")\nadd_document(\"A quick jump is good exercise.\", \"file3.txt\")\n\nindex.flush()\nindex.close()\n\n# 3. Perform a search\nsearch_index = SKIndex.alloc().initForURL_create_dictionary_(index_url, False, None)\nif not search_index:\n    print(\"Failed to open SearchKit index for searching.\")\n    shutil.rmtree(temp_dir)\n    exit()\n\nsearch_query = \"quick dog\"\nprint(f\"\\nSearching for: '{search_query}'\")\n\nsearch = SKSearch.alloc().initWithIndex_(\n    search_index\n)\n\nif search:\n    search_options = kSKSearchOptionNone\n    search_group = SKSearchGroup.alloc().init()\n    # You can specify the maximum number of results\n    results = search.findMatchesForQuery_maxCount_(\n        search_query,\n        10 # Max 10 results\n    )\n\n    if results:\n        for i, doc_ref in enumerate(results.objectAtIndex_(0)):\n            score = results.objectAtIndex_(1)[i]\n            # Get original document URL (which we used as a dummy path)\n            doc_url = search_index.documentPropertiesForDocumentRef_(doc_ref).objectForKey_(\"kSKDocumentURL\").path()\n            print(f\"  Match: {doc_url} (Score: {score:.2f})\")\n    else:\n        print(\"  No matches found.\")\nelse:\n    print(\"Failed to create SKSearch object.\")\n\nsearch_index.close()\n\n# 4. Clean up\nshutil.rmtree(temp_dir)\nprint(f\"\\nCleaned up temporary index directory: {temp_dir}\")\n","lang":"python","description":"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).","tag":null,"tag_description":null,"last_tested":null,"results":[]},"compatibility":{"tag":null,"tag_description":null,"last_tested":"2026-05-16","installed_version":null,"pypi_latest":"12.1","is_stale":null,"summary":{"python_range":"3.10–3.9","success_rate":0,"avg_install_s":null,"avg_import_s":null,"wheel_type":null},"results":[{"runtime":"python:3.10-alpine","python_version":"3.10","os_libc":"alpine (musl)","variant":"pyobjc","exit_code":1,"wheel_type":null,"failure_reason":"build_error","import_side_effects":null,"install_time_s":null,"import_time_s":null,"mem_mb":null,"disk_size":null},{"runtime":"python:3.10-alpine","python_version":"3.10","os_libc":"alpine (musl)","variant":"pyobjc-framework-searchkit","exit_code":1,"wheel_type":null,"failure_reason":"build_error","import_side_effects":null,"install_time_s":null,"import_time_s":null,"mem_mb":null,"disk_size":null},{"runtime":"python:3.10-slim","python_version":"3.10","os_libc":"slim (glibc)","variant":"pyobjc","exit_code":1,"wheel_type":null,"failure_reason":"build_error","import_side_effects":null,"install_time_s":3.2,"import_time_s":null,"mem_mb":null,"disk_size":null},{"runtime":"python:3.10-slim","python_version":"3.10","os_libc":"slim (glibc)","variant":"pyobjc-framework-searchkit","exit_code":1,"wheel_type":null,"failure_reason":"build_error","import_side_effects":null,"install_time_s":3,"import_time_s":null,"mem_mb":null,"disk_size":null},{"runtime":"python:3.11-alpine","python_version":"3.11","os_libc":"alpine (musl)","variant":"pyobjc","exit_code":1,"wheel_type":null,"failure_reason":"build_error","import_side_effects":null,"install_time_s":null,"import_time_s":null,"mem_mb":null,"disk_size":null},{"runtime":"python:3.11-alpine","python_version":"3.11","os_libc":"alpine (musl)","variant":"pyobjc-framework-searchkit","exit_code":1,"wheel_type":null,"failure_reason":"build_error","import_side_effects":null,"install_time_s":null,"import_time_s":null,"mem_mb":null,"disk_size":null},{"runtime":"python:3.11-slim","python_version":"3.11","os_libc":"slim (glibc)","variant":"pyobjc","exit_code":1,"wheel_type":null,"failure_reason":"build_error","import_side_effects":null,"install_time_s":3.3,"import_time_s":null,"mem_mb":null,"disk_size":null},{"runtime":"python:3.11-slim","python_version":"3.11","os_libc":"slim (glibc)","variant":"pyobjc-framework-searchkit","exit_code":1,"wheel_type":null,"failure_reason":"build_error","import_side_effects":null,"install_time_s":3.1,"import_time_s":null,"mem_mb":null,"disk_size":null},{"runtime":"python:3.12-alpine","python_version":"3.12","os_libc":"alpine (musl)","variant":"pyobjc","exit_code":1,"wheel_type":null,"failure_reason":"build_error","import_side_effects":null,"install_time_s":null,"import_time_s":null,"mem_mb":null,"disk_size":null},{"runtime":"python:3.12-alpine","python_version":"3.12","os_libc":"alpine (musl)","variant":"pyobjc-framework-searchkit","exit_code":1,"wheel_type":null,"failure_reason":"build_error","import_side_effects":null,"install_time_s":null,"import_time_s":null,"mem_mb":null,"disk_size":null},{"runtime":"python:3.12-slim","python_version":"3.12","os_libc":"slim (glibc)","variant":"pyobjc","exit_code":1,"wheel_type":null,"failure_reason":"build_error","import_side_effects":null,"install_time_s":1.4,"import_time_s":null,"mem_mb":null,"disk_size":null},{"runtime":"python:3.12-slim","python_version":"3.12","os_libc":"slim (glibc)","variant":"pyobjc-framework-searchkit","exit_code":1,"wheel_type":null,"failure_reason":"build_error","import_side_effects":null,"install_time_s":3.1,"import_time_s":null,"mem_mb":null,"disk_size":null},{"runtime":"python:3.13-alpine","python_version":"3.13","os_libc":"alpine (musl)","variant":"pyobjc","exit_code":1,"wheel_type":null,"failure_reason":"build_error","import_side_effects":null,"install_time_s":null,"import_time_s":null,"mem_mb":null,"disk_size":null},{"runtime":"python:3.13-alpine","python_version":"3.13","os_libc":"alpine (musl)","variant":"pyobjc-framework-searchkit","exit_code":1,"wheel_type":null,"failure_reason":"build_error","import_side_effects":null,"install_time_s":null,"import_time_s":null,"mem_mb":null,"disk_size":null},{"runtime":"python:3.13-slim","python_version":"3.13","os_libc":"slim (glibc)","variant":"pyobjc","exit_code":1,"wheel_type":null,"failure_reason":"build_error","import_side_effects":null,"install_time_s":2.6,"import_time_s":null,"mem_mb":null,"disk_size":null},{"runtime":"python:3.13-slim","python_version":"3.13","os_libc":"slim (glibc)","variant":"pyobjc-framework-searchkit","exit_code":1,"wheel_type":null,"failure_reason":"build_error","import_side_effects":null,"install_time_s":2.7,"import_time_s":null,"mem_mb":null,"disk_size":null},{"runtime":"python:3.9-alpine","python_version":"3.9","os_libc":"alpine (musl)","variant":"pyobjc","exit_code":1,"wheel_type":null,"failure_reason":"build_error","import_side_effects":null,"install_time_s":null,"import_time_s":null,"mem_mb":null,"disk_size":null},{"runtime":"python:3.9-alpine","python_version":"3.9","os_libc":"alpine (musl)","variant":"pyobjc-framework-searchkit","exit_code":1,"wheel_type":null,"failure_reason":"build_error","import_side_effects":null,"install_time_s":null,"import_time_s":null,"mem_mb":null,"disk_size":null},{"runtime":"python:3.9-slim","python_version":"3.9","os_libc":"slim (glibc)","variant":"pyobjc","exit_code":1,"wheel_type":null,"failure_reason":"build_error","import_side_effects":null,"install_time_s":3.7,"import_time_s":null,"mem_mb":null,"disk_size":null},{"runtime":"python:3.9-slim","python_version":"3.9","os_libc":"slim (glibc)","variant":"pyobjc-framework-searchkit","exit_code":1,"wheel_type":null,"failure_reason":"build_error","import_side_effects":null,"install_time_s":3.6,"import_time_s":null,"mem_mb":null,"disk_size":null}]}}