2121from google .cloud import client as google_client
2222from google .cloud .datastore_v1 .gapic import datastore_client
2323
24- DATASTORE_API_HOST = datastore_client .DatastoreClient .SERVICE_ADDRESS .rstrip (
25- ":443"
26- )
24+ from google .cloud .ndb import _runstate
25+
26+ DATASTORE_API_HOST = datastore_client .DatastoreClient .SERVICE_ADDRESS .rsplit (
27+ ":" , 1
28+ )[0 ]
2729
2830
2931def _get_gcd_project ():
@@ -60,6 +62,9 @@ def _determine_default_project(project=None):
6062class Client (google_client .ClientWithProject ):
6163 """An NDB client.
6264
65+ The NDB client must be created in order to use NDB, and any use of NDB must
66+ be within the context of a call to :meth:`context`.
67+
6368 Arguments:
6469 project (Optional[str]): The project to pass to proxied API methods. If
6570 not passed, falls back to the default inferred from the
@@ -73,15 +78,45 @@ class Client(google_client.ClientWithProject):
7378 SCOPE = ("https://www.googleapis.com/auth/datastore" ,)
7479 """The scopes required for authenticating as a Cloud Datastore consumer."""
7580
76- secure = True
77- """Whether to use a secure connection for API calls."""
78-
7981 def __init__ (self , project = None , namespace = None , credentials = None ):
8082 super (Client , self ).__init__ (project = project , credentials = credentials )
8183 self .namespace = namespace
8284 self .host = os .environ .get (
8385 environment_vars .GCD_HOST , DATASTORE_API_HOST
8486 )
87+ self .secure = True
88+
89+ def context (self ):
90+ """Establish a context for a set of NDB calls.
91+
92+ This method provides a context manager which establishes the runtime
93+ state for using NDB.
94+
95+ For example:
96+
97+ .. code-block:: python
98+
99+ from google.cloud import ndb
100+
101+ client = ndb.Client()
102+ with client.context():
103+ # Use NDB for some stuff
104+ pass
105+
106+ Use of a context is required--NDB can only be used inside a running
107+ context. The context is used to manage the connection to Google Cloud
108+ Datastore, an event loop for asynchronous API calls, runtime caching
109+ policy, and other essential runtime state.
110+
111+ Code within an asynchronous context should be single threaded.
112+ Internally, a :class:`threading.local` instance is used to track the
113+ current event loop.
114+
115+ In a web application, it is recommended that a single context be used
116+ per HTTP request. This can typically be accomplished in a middleware
117+ layer.
118+ """
119+ return _runstate .state_context (self )
85120
86121 @property
87122 def _http (self ):
0 commit comments