@@ -521,15 +521,23 @@ Priority: ``auth`` callable > ``auth_token`` > ``http_user/http_pass``.
521521SolrCloud
522522---------
523523
524- **With ZooKeeper ** (real-time node discovery, requires ``kazoo ``)::
524+ Install ZooKeeper support::
525+
526+ pip install solrpy[cloud]
527+
528+ **With ZooKeeper ** (real-time node discovery via ``kazoo ``)::
525529
526530 from solr import SolrZooKeeper, SolrCloud
527531
528- zk = SolrZooKeeper('zk1:2181,zk2:2181')
529- cloud = SolrCloud(zk, collection='mycore ')
532+ zk = SolrZooKeeper('zk1:2181,zk2:2181,zk3:2181 ')
533+ cloud = SolrCloud(zk, collection='products ')
530534
531- response = cloud.select('*:*')
532- cloud.add({'id': '1', 'title': 'test'}, commit=True)
535+ # Reads go to any active replica (automatic failover)
536+ response = cloud.select('category:books', rows=20)
537+
538+ # Writes are routed to shard leaders
539+ cloud.add({'id': '1', 'title': 'Solr in Action'}, commit=True)
540+ cloud.delete(id='1', commit=True)
533541
534542 cloud.close()
535543 zk.close()
@@ -540,14 +548,58 @@ SolrCloud
540548
541549 cloud = SolrCloud.from_urls(
542550 ['http://solr1:8983/solr', 'http://solr2:8983/solr'],
543- collection='mycore ')
551+ collection='products ')
544552
545553 response = cloud.select('*:*')
546554 cloud.close()
547555
548- Install ZooKeeper support ::
556+ Pass connection options (timeout, auth, SSL) via `` **solr_kwargs `` ::
549557
550- pip install solrpy[cloud]
558+ cloud = SolrCloud(zk, collection='secure',
559+ timeout=10,
560+ auth_token='my-jwt-token')
561+
562+ Failover retries default to 3 with exponential backoff::
563+
564+ # Customize retry behavior
565+ cloud = SolrCloud(zk, collection='products',
566+ retry_count=5, retry_delay=1.0)
567+
568+
569+ Using SolrZooKeeper directly
570+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
571+
572+ You can also use ``SolrZooKeeper `` independently for cluster inspection::
573+
574+ from solr import SolrZooKeeper
575+
576+ zk = SolrZooKeeper('zk1:2181,zk2:2181')
577+
578+ # List active nodes
579+ print(zk.live_nodes())
580+ # ['solr1:8983_solr', 'solr2:8983_solr', 'solr3:8983_solr']
581+
582+ # Get all replica URLs for a collection
583+ replicas = zk.replica_urls('products')
584+ # ['http://solr1:8983/solr', 'http://solr2:8983/solr']
585+
586+ # Get shard leader URLs (one per shard)
587+ leaders = zk.leader_urls('products')
588+ # ['http://solr1:8983/solr']
589+
590+ # Check collection aliases
591+ aliases = zk.aliases()
592+ # {'prod': 'products_v2', 'staging': 'products_v1'}
593+
594+ # Aliases are resolved automatically in replica_urls/leader_urls
595+ zk.replica_urls('prod') # same as zk.replica_urls('products_v2')
596+
597+ # Inspect collection state (shards, replicas, router)
598+ state = zk.collection_state('products')
599+ for shard, data in state['shards'].items():
600+ print(shard, len(data['replicas']), 'replicas')
601+
602+ zk.close()
551603
552604
553605Pydantic response models
@@ -576,6 +628,41 @@ Convert search results to typed Pydantic models (``pip install solrpy[pydantic]`
576628 products = resp.as_models(Product)
577629
578630
631+ Async usage
632+ -----------
633+
634+ Use ``AsyncSolr `` for async/await support (e.g. in FastAPI, aiohttp)::
635+
636+ from solr import AsyncSolr
637+
638+ async with AsyncSolr('http://localhost:8983/solr/mycore') as conn:
639+ response = await conn.select('*:*')
640+ for doc in response.results:
641+ print(doc['id'])
642+
643+ Unified sync/async companions
644+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
645+
646+ Since 2.0.4, all companion classes work with both ``Solr `` and ``AsyncSolr ``.
647+ No need for separate ``AsyncSchemaAPI ``, ``AsyncKNN ``, etc.::
648+
649+ from solr import Solr, AsyncSolr, SchemaAPI, KNN
650+
651+ # Sync
652+ conn = Solr('http://localhost:8983/solr/mycore')
653+ schema = SchemaAPI(conn)
654+ fields = schema.fields()
655+
656+ # Async — same class, returns coroutines
657+ async with AsyncSolr('http://localhost:8983/solr/mycore') as conn:
658+ schema = SchemaAPI(conn)
659+ fields = await schema.fields()
660+
661+ The ``AsyncSchemaAPI ``, ``AsyncKNN ``, ``AsyncMoreLikeThis ``,
662+ ``AsyncSuggest ``, and ``AsyncExtract `` names are kept as backward-compatible
663+ aliases.
664+
665+
579666Closing the connection
580667----------------------
581668
0 commit comments