{"id":170,"library":"typesense","title":"Typesense Python Client","description":"Official Python client for Typesense — open source typo-tolerant search engine, alternative to Algolia/Elasticsearch. Current version: 2.0.0 (Mar 2026). v2.0 added AsyncClient. Client takes a config dict with 'nodes' list — not a URL string. Typesense Cloud uses port 443 and HTTPS. Self-hosted uses port 8108 and HTTP by default.","status":"active","version":"2.0.0","language":"python","source_language":"en","source_url":"https://github.com/typesense/typesense-python","tags":["typesense","search","python","fulltext","vector-search","algolia-alternative"],"install":[{"cmd":"pip install typesense","lang":"bash","label":"Python (sync + async)"}],"dependencies":[],"imports":[{"note":"Client takes a config dict with a 'nodes' list — not a URL string. nodes is always a list even for single-node setups.","wrong":"import typesense\n# Wrong: URL string instead of config dict\nclient = typesense.Client('http://localhost:8108')\n# Wrong: no nodes list\nclient = typesense.Client({'api_key': 'key', 'host': 'localhost'})","symbol":"Client (sync)","correct":"import typesense\n\nclient = typesense.Client({\n    'nodes': [{\n        'host': 'localhost',\n        'port': '8108',\n        'protocol': 'http'\n    }],\n    'api_key': 'your-api-key',\n    'connection_timeout_seconds': 2\n})\n\n# Create collection\nclient.collections.create({\n    'name': 'products',\n    'fields': [\n        {'name': 'name', 'type': 'string'},\n        {'name': 'price', 'type': 'float'}\n    ],\n    'default_sorting_field': 'price'\n})\n\n# Index document\nclient.collections['products'].documents.create({\n    'id': '1',\n    'name': 'Widget',\n    'price': 9.99\n})\n\n# Search\nresult = client.collections['products'].documents.search({\n    'q': 'widget',\n    'query_by': 'name'\n})"},{"note":"AsyncClient added in v2.0. Must call await client.api_call.aclose() when done to close HTTP connections.","wrong":"","symbol":"AsyncClient (v2.0+)","correct":"import typesense\nimport asyncio\n\nasync def main():\n    client = typesense.AsyncClient({\n        'nodes': [{\n            'host': 'localhost',\n            'port': '8108',\n            'protocol': 'http'\n        }],\n        'api_key': 'your-api-key',\n        'connection_timeout_seconds': 2\n    })\n    result = await client.collections.retrieve()\n    await client.api_call.aclose()  # must close\n    return result\n\nasyncio.run(main())"}],"quickstart":{"code":"# pip install typesense\nimport typesense\n\n# Self-hosted\nclient = typesense.Client({\n    'nodes': [{'host': 'localhost', 'port': '8108', 'protocol': 'http'}],\n    'api_key': 'your-api-key',\n    'connection_timeout_seconds': 2\n})\n\n# Typesense Cloud\n# client = typesense.Client({\n#     'nodes': [{'host': 'xxx.a1.typesense.net', 'port': '443', 'protocol': 'https'}],\n#     'api_key': 'your-cloud-api-key',\n#     'connection_timeout_seconds': 2\n# })\n\n# Create collection with schema\nclient.collections.create({\n    'name': 'books',\n    'fields': [\n        {'name': 'title', 'type': 'string'},\n        {'name': 'author', 'type': 'string', 'facet': True},\n        {'name': 'year', 'type': 'int32'}\n    ]\n})\n\n# Index\nclient.collections['books'].documents.create({\n    'id': '1', 'title': 'Dune', 'author': 'Herbert', 'year': 1965\n})\n\n# Search\nresult = client.collections['books'].documents.search({\n    'q': 'dune',\n    'query_by': 'title,author'\n})\nprint(result['hits'])","lang":"python","description":"Typesense Python client — collection creation, indexing, and search."},"warnings":[{"fix":"Always: {'nodes': [{'host': '...', 'port': '8108', 'protocol': 'http'}], 'api_key': '...'}","message":"Client config requires 'nodes' as a list — not a URL string or flat host/port keys. Passing a URL string raises TypeError.","severity":"gotcha","affected_versions":"all"},{"fix":"Cloud: port='443', protocol='https'. Self-hosted: port='8108', protocol='http'.","message":"Typesense Cloud uses port 443 and protocol 'https'. Self-hosted defaults to port 8108 and 'http'. Mixing these up causes connection errors.","severity":"gotcha","affected_versions":"all"},{"fix":"Always call client.collections.create({...}) before indexing documents.","message":"Collection schema is required before indexing — Typesense is schema-enforced unlike Elasticsearch. Indexing without creating collection first raises ObjectNotFound.","severity":"gotcha","affected_versions":"all"},{"fix":"Always stringify IDs: {'id': str(record_id), ...}","message":"document 'id' field must be a string — not an integer. Passing int raises validation error.","severity":"gotcha","affected_versions":"all"},{"fix":"await client.api_call.aclose() when done, or use try/finally.","message":"AsyncClient (v2.0) requires await client.api_call.aclose() to close connections. Omitting this leaks HTTP connections.","severity":"gotcha","affected_versions":">= 2.0"},{"fix":"See https://github.com/typesense/typesense-python for compatibility matrix.","message":"Client version should match Typesense server version. Python client v2.0 targets Typesense server v26+. Check compatibility matrix.","severity":"gotcha","affected_versions":"all"}],"env_vars":null,"last_verified":"2026-05-12T09:14:09.466Z","next_check":"2026-06-24T00:00:00.000Z","problems":[{"fix":"pip install typesense","cause":"The 'typesense' Python client library has not been installed in the current development environment.","error":"ModuleNotFoundError: No module named 'typesense'"},{"fix":"client = typesense.Client({\n  'nodes': [{\n    'host': 'localhost',\n    'port': '8108',\n    'protocol': 'http' # Use 'https' for Typesense Cloud\n  }],\n  'api_key': 'your_api_key'\n})","cause":"The `typesense.Client` constructor requires a configuration dictionary that includes a 'nodes' key, which is a list of server node configurations.","error":"KeyError: 'nodes'"},{"fix":"Verify the Typesense server is running and that the `host`, `port`, and `protocol` in your client configuration accurately match the server's address and access settings.","cause":"The Typesense server is either not running, not accessible at the specified host and port, or a firewall is blocking the connection.","error":"typesense.exceptions.TypesenseClientError: Connection refused"},{"fix":"async def my_async_function():\n    # ... async client setup ...\n    schema = {'name': 'my_collection', 'fields': [{'name': 'id', 'type': 'string'}]}\n    collection = await async_client.collections.create(schema) # Prepend 'await'\n    print(collection['name'])","cause":"Methods of `typesense.AsyncClient` return asynchronous coroutine objects that must be awaited to execute and yield their results, but the `await` keyword was omitted.","error":"TypeError: 'coroutine' object is not subscriptable"},{"fix":"Update the `api_key` in your `typesense.Client` configuration to a valid Typesense API key with the required permissions.","cause":"The API key provided in the `typesense.Client` configuration is either incorrect or lacks the necessary permissions for the requested operation.","error":"typesense.exceptions.TypesenseClientError: [401] Unauthorized"}],"ecosystem":"pypi","meta_description":null,"install_score":100,"install_tag":"verified","quickstart_score":0,"quickstart_tag":"stale","pypi_latest":null,"install_checks":{"last_tested":"2026-05-12","tag":"verified","tag_description":"installs cleanly on critical runtimes, fast import, recently tested","results":[{"runtime":"python:3.10-alpine","python_version":"3.10","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.31,"mem_mb":8.8,"disk_size":"23.3M"},{"runtime":"python:3.10-slim","python_version":"3.10","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.23,"mem_mb":8.8,"disk_size":"24M"},{"runtime":"python:3.11-alpine","python_version":"3.11","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.46,"mem_mb":9.5,"disk_size":"25.6M"},{"runtime":"python:3.11-slim","python_version":"3.11","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.36,"mem_mb":9.5,"disk_size":"26M"},{"runtime":"python:3.12-alpine","python_version":"3.12","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.36,"mem_mb":9.3,"disk_size":"17.4M"},{"runtime":"python:3.12-slim","python_version":"3.12","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.38,"mem_mb":9.3,"disk_size":"18M"},{"runtime":"python:3.13-alpine","python_version":"3.13","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.35,"mem_mb":9.7,"disk_size":"17.0M"},{"runtime":"python:3.13-slim","python_version":"3.13","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.35,"mem_mb":9.7,"disk_size":"18M"},{"runtime":"python:3.9-alpine","python_version":"3.9","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.29,"mem_mb":8.7,"disk_size":"22.6M"},{"runtime":"python:3.9-slim","python_version":"3.9","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.27,"mem_mb":8.7,"disk_size":"23M"}]},"quickstart_checks":{"last_tested":"2026-04-23","tag":"stale","tag_description":"widespread failures or data too old to trust","results":[{"runtime":"python:3.10-alpine","exit_code":1},{"runtime":"python:3.10-slim","exit_code":1},{"runtime":"python:3.11-alpine","exit_code":1},{"runtime":"python:3.11-slim","exit_code":1},{"runtime":"python:3.12-alpine","exit_code":1},{"runtime":"python:3.12-slim","exit_code":1},{"runtime":"python:3.13-alpine","exit_code":1},{"runtime":"python:3.13-slim","exit_code":1},{"runtime":"python:3.9-alpine","exit_code":1},{"runtime":"python:3.9-slim","exit_code":1}]}}