diff --git a/qdrant-landing/content/documentation/tutorials/async-api.md b/qdrant-landing/content/documentation/tutorials/async-api.md index 83e11c80f..eb9ae9003 100644 --- a/qdrant-landing/content/documentation/tutorials/async-api.md +++ b/qdrant-landing/content/documentation/tutorials/async-api.md @@ -5,23 +5,21 @@ weight: 18 # Using Qdrant asynchronously -Asynchronous programming is being broadly adopted in the Python ecosystem. Tools such as FastAPI [have embraced that new -paradigm](https://fastapi.tiangolo.com/async/), but it's also becoming a standard for ML models served as SaaS. For example, the Cohere SDK +Asynchronous programming is being broadly adopted in the Python ecosystem. Tools such as FastAPI [have embraced this new +paradigm](https://fastapi.tiangolo.com/async/), but it is also becoming a standard for ML models served as SaaS. For example, the Cohere SDK [provides an async client](https://cohere-sdk.readthedocs.io/en/latest/cohere.html#asyncclient) next to its synchronous counterpart. Databases are often launched as separate services and are accessed via a network. All the interactions with them are IO-bound and can -be performed asynchronously so as not to waste time actively waiting for a server response. If you use Python, that is achieved by +be performed asynchronously so as not to waste time actively waiting for a server response. In Python, this is achieved by using [`async/await`](https://docs.python.org/3/library/asyncio-task.html) syntax. That lets the interpreter switch to another task while waiting for a response from the server. Qdrant exposes two interfaces: HTTP and gRPC. The official SDKs for different languages are based on the autogenerated clients, and -in Python [qdrant-client](https://github.com/qdrant/qdrant-client), you can call all the methods asynchronously. This tutorial presents -how to do it. +in Python [qdrant-client](https://github.com/qdrant/qdrant-client), you can call all the methods asynchronously. This tutorial will teach you how to do just that. -## When the usage of async API is justified? +## When to use async API -If the application you are writing will never support multiple users at once, for example, it is a script run once daily, then there -is no need to use async API. But if you are writing a web service that multiple users will use simultaneously, you shouldn't be +There is no need to use async API if the application you are writing will never support multiple users at once (e.g it is a script that runs once per day). However, if you are writing a web service that multiple users will use simultaneously, you shouldn't be blocking the threads of the web server as it limits the number of concurrent requests it can handle. In this case, you should use the async API. @@ -31,9 +29,9 @@ cannot be used in synchronous functions. On the other hand, calling an IO-bound an antipattern. Therefore, if you build an async web service, exposed through an [ASGI](https://asgi.readthedocs.io/en/latest/) server, you should use the async API for all the interactions with Qdrant. -## How to use async API? +## How to use async API -Calling any method of Qdrant requires establishing a connection to the server. We need to create an instance of `QdrantClient` +Calling any method of Qdrant requires establishing a connection to the server. You need to create an instance of `QdrantClient` that will act as a gateway. If you want to do it locally, please make sure Qdrant server is running. If it's not, then you can launch it in a Docker container: @@ -55,16 +53,16 @@ client = QdrantClient("localhost") # client = QdrantClient("https://your-cluster-url.cloud.com", api_key="your-api-key") ``` -The default client only exposes the synchronous methods for interacting with the server. To access the async client and it's underlying methods, we need to use autogenerated async clients. -It is possible to use asynchronous HTTP API by using `qdrant_client.http.api_client.AsyncApis`. The asynchronous gRPC API if more efficient than the HTTP API, which is why we recommend you use it and we will be using it here. +The default client only exposes the synchronous methods for interacting with the server. To access the async client and it's underlying methods, you need to use autogenerated async clients. +It is possible to use asynchronous HTTP API by using `qdrant_client.http.api_client.AsyncApis`. We recommend you use the asynchronous gRPC API, as it is more efficient than the HTTP API. ### gRPC API -Every instance of `QdrantClient` has two properties we are going to use: `async_grpc_collections` and `async_grpc_points`. They expose +Every instance of `QdrantClient` has two properties: `async_grpc_collections` and `async_grpc_points`. They expose the autogenerated clients for [collections](/documentation/concepts/collections/) and [points](/documentation/concepts/points/) respectively. -The gRPC client uses type definitions for all the interactions with the server. They are autogenerated from the source code of Qdrant -server, and we have to import them if we want to call any of the available methods. +The gRPC client uses type definitions for all interactions with the server. They are autogenerated from the source code of Qdrant +server, and you have to import them if you want to call any of the available methods. ```python from qdrant_client import grpc @@ -103,7 +101,7 @@ if the server does not respond within 10 seconds, the request will be aborted. #### Checking collection info -We can check the collection info to see if it was created successfully, and configured as we expected: +You can check the collection info to see if it was created and properly configured: ```python response = await client.async_grpc_collections.Get( @@ -113,7 +111,7 @@ response = await client.async_grpc_collections.Get( ) ``` -The `response` object is going to be an instance of `grpc.GetCollectionInfoResponse` and we can access the fields we need or simply +The `response` object is going to be an instance of `grpc.GetCollectionInfoResponse` and you can access the fields you need or simply display its content. ```python @@ -224,11 +222,10 @@ await client.async_grpc_collections.Update( #### Deleting a collection -There is plenty of other methods available for collections, like creating aliases or checking the status of the cluster. We are not going -to call all of them in this tutorial, but you can always [check the list of available methods and their parameters in the +There are plenty of methods available for collections, such as creating aliases or checking the status of the cluster. This tutorial won't use all of them, but you can always [check the list of available methods and their parameters in the documentation](https://github.com/qdrant/qdrant/blob/master/docs/grpc/docs.md#collections_serviceproto). -Right now, we are just going to delete the collection we created: +Right now, you can just delete the collection you created: ```python await client.async_grpc_collections.Delete( @@ -237,12 +234,11 @@ await client.async_grpc_collections.Delete( ) ) ``` - That's it when it comes to collection management. Let's move on to points (individual vectors) allowing us to load data into our collection #### Adding points to the collection -Assuming your collection created successfuly, we can now add some +Assuming your collection was created successfuly, you can now add some points to it. Let's add our first two points into the collection: ```python @@ -279,15 +275,13 @@ response = await client.async_grpc_points.Upsert( ) ``` -Those points are automatically indexed and available for search. In the future, we can add more points, or update the existing ones. All the point related -operations are [documented in the Qdrant server repository](https://github.com/qdrant/qdrant/blob/master/docs/grpc/docs.md#points_serviceproto). +Those points are automatically indexed and available for search. In the future, you can add more points, or update the existing ones. All point related operations are [documented in the Qdrant server repository](https://github.com/qdrant/qdrant/blob/master/docs/grpc/docs.md#points_serviceproto). -The main operation we need from the vector database is semantic search. Let's see how to perform it. +The main operation you need from the vector database is semantic search. Let's see how to perform it. #### Asynchronous semantic search -Search operation requires a query vector and a collection name. We can also specify the number of results we want to retrieve and some other -parameters, but let's take one step at a time. The minimal example may look like this: +The search operation requires a query vector and a collection name. You can also specify the number of results you want to retrieve and some other parameters. A minimal example might look like this: ```python response = await client.async_grpc_points.Search( @@ -334,8 +328,7 @@ That's all the code you need to bring back the vector and payload. ##### Applying filters -If you ever used SQL, you are probably familiar with the `WHERE` clause. It allows you to filter the results of the query. Qdrant has similar -functionality. Let's say we want to find all the points similar to given vector, but with `int_param` equal to 32. We can do it like this: +If you ever used SQL, you are probably familiar with the `WHERE` clause. It lets you filter the results of the query. Qdrant has a similar functionality. Imagine you want to find all the points similar to given vector, but with `int_param` equal to 32. You can do it like this: ```python response = await client.async_grpc_points.Search( @@ -358,15 +351,12 @@ response = await client.async_grpc_points.Search( ) ``` -We can build even more sophisticated filters with the `must`, `should` and `must_not` clauses. You can find more details in the [filtering -documentation](https://qdrant.tech/documentation/concepts/filtering/#filtering). +You can build even more sophisticated filters with the `must`, `should` and `must_not` clauses. You can find more details in the [filtering documentation](https://qdrant.tech/documentation/concepts/filtering/#filtering). -Analogous to search, we can also [scroll our collection](https://qdrant.tech/documentation/concepts/points/#scroll-points) to retrieve all the -points or use the [recommendation API](https://qdrant.tech/documentation/concepts/search/#recommendation-api) to find points similar to positive -and dissimilar to negative examples. +Analogous to search, you can also [scroll our collection](https://qdrant.tech/documentation/concepts/points/#scroll-points) to retrieve all the points or use the [recommendation API](https://qdrant.tech/documentation/concepts/search/#recommendation-api) to find points similar to positive and dissimilar to negative examples. ## Support of Qdrant async API in Python libraries -There is plenty of Python libraries that Qdrant integrates with. Until recently, only [Langchain]() provided async Python API support. -Qdrant is the only vector database with full coverage of async API in Langchain. The documentation [describes how to use +Qdrant integrates with numerous Python libraries. Until recently, only [Langchain]() provided async Python API support. +Qdrant is the only vector database with full coverage of async API in Langchain. Their documentation [describes how to use it](https://python.langchain.com/docs/modules/data_connection/vectorstores/#asynchronous-operations).