Handing sessions with a context manager¶
By default, the Refinitiv Data Library for Python expects you to open and close a session manually, typically done with the open_session
and close_session
functions.
This can lead to problems if you forget to close your session, and it can require you to write more code than you might like.
That can be avoided by using a context manager. Context managers allow you to create a block of code that is executed when you enter and exit a with
statement. A common example from Python’s standard library is opening and closing a file like so:
with open("my_file.txt", "w") as f:
f.write("Hello, world!")
Here’s how to create a custom context manager that will open and close a Refinitiv Data Library for Python session:
from contextlib import contextmanager
import refinitiv.data as rd
@contextmanager
def rd_session():
"""Context manager for handling a Refinitiv Data Library for Python session."""
try:
# Create a session and return it
rd.open_session()
yield
finally:
# Close the session
rd.close_session()
Once that’s been introduced to your code, you can open a session by running the following code:
with rd_session():
# Do whatever you want to do your `rd` session in the indent ...
pass
/home/runner/.local/share/virtualenvs/refinitiv-data-python-cookbook-I-HIyNf4/lib/python3.10/site-packages/refinitiv/data/_access_layer/session.py:71:FutureWarning:
You open a platform session using the default value of the signon_control parameter (signon_control=True).
In future library version v2.0, this default will be changed to False.
If you want to keep the same behavior as today, you will need to set the signon_control parameter to True either in the library configuration file
({'sessions':{'platform':{'your_session_name':{'signon_control':true}}}}) or in your code where you create the Platform Session.
These alternative options are already supported in the current version of the library.
[Error 400] - {'error': 'access_denied', 'error_description': 'Account locked out due to provide incorrect password.'}
Once the indent is removed, the session will be closed automatically. Here’s how you could use it to get the current price of Thomson Reuters stock:
with rd_session():
df = rd.get_history('TRI.N')
df.head(5)
---------------------------------------------------------------------------
KeyboardInterrupt Traceback (most recent call last)
Cell In[3], line 1
----> 1 with rd_session():
2 df = rd.get_history('TRI.N')
4 df.head(5)
File /opt/hostedtoolcache/Python/3.10.16/x64/lib/python3.10/contextlib.py:135, in _GeneratorContextManager.__enter__(self)
133 del self.args, self.kwds, self.func
134 try:
--> 135 return next(self.gen)
136 except StopIteration:
137 raise RuntimeError("generator didn't yield") from None
Cell In[1], line 11, in rd_session()
8 """Context manager for handling a Refinitiv Data Library for Python session."""
9 try:
10 # Create a session and return it
---> 11 rd.open_session()
12 yield
13 finally:
14 # Close the session
File ~/.local/share/virtualenvs/refinitiv-data-python-cookbook-I-HIyNf4/lib/python3.10/site-packages/refinitiv/data/_access_layer/session.py:91, in open_session(name, app_key, config_name)
88 set_default(new_session)
89 default_session = new_session
---> 91 default_session.open()
93 return default_session
File ~/.local/share/virtualenvs/refinitiv-data-python-cookbook-I-HIyNf4/lib/python3.10/site-packages/refinitiv/data/_core/session/_session.py:395, in Session.open(self)
393 self._config.on(configure.ConfigEvent.UPDATE, self._on_config_updated)
394 self._http_service.open()
--> 395 is_opened = self._connection.open()
397 if is_opened:
398 self._state = OpenState.Opened
File ~/.local/share/virtualenvs/refinitiv-data-python-cookbook-I-HIyNf4/lib/python3.10/site-packages/refinitiv/data/_core/session/connection.py:261, in RefinitivDataConnection.open(self)
260 def open(self) -> bool:
--> 261 is_opened = self.auth_manager.authorize()
262 return is_opened
File ~/.local/share/virtualenvs/refinitiv-data-python-cookbook-I-HIyNf4/lib/python3.10/site-packages/refinitiv/data/_core/session/auth/_auth_manager.py:132, in AuthManager.authorize(self)
129 self._thread.start()
131 if not self.is_closed() and not self._disposed:
--> 132 self._result_evt.wait()
134 is_authorized = self.is_authorized()
135 is_debug and self.debug(f"AuthManager: end authorize, result {is_authorized}")
File /opt/hostedtoolcache/Python/3.10.16/x64/lib/python3.10/threading.py:607, in Event.wait(self, timeout)
605 signaled = self._flag
606 if not signaled:
--> 607 signaled = self._cond.wait(timeout)
608 return signaled
File /opt/hostedtoolcache/Python/3.10.16/x64/lib/python3.10/threading.py:320, in Condition.wait(self, timeout)
318 try: # restore state no matter what (e.g., KeyboardInterrupt)
319 if timeout is None:
--> 320 waiter.acquire()
321 gotit = True
322 else:
KeyboardInterrupt: