Session : Unravelling a mysterious object (Part1)

Okay, so today I'm going to tell you a little story through code. This is a partial story about session and my encounters with this mysterious entity. Bear with me, it's going to be a ride (probably a trippy one).

Prerequisite knowledge: – Python (intro level), – HTTP request methods

I first encountered this object, not just under that generic name, but as a mysterious entity that did other things. Those who received this session, said it was of a particular type (or kind) ~keystoneauth1.adapter.Adapter That description seemed just as cryptic. But it did give a hint.

Here's a sample of our first meet.

    #location: openstacksdk/openstack/baremetal/v1/ - Node/

        def commit(self, session, *args, **kwargs):
        """Commit the state of the instance to the remote resource.

        :param session: The session to use for making this request.
        :type session: :class:`~keystoneauth1.adapter.Adapter`

        :return: This :class:`Node` instance.

Hmm. Now what did that tell me? That there is this function called commit. And it receives this session gladly as a parameter (required it, in fact). commit says session is of some particular type.

Now, I had not encountered this type before. But from the name I figured this session was someone that authenticated you and then allowed you to do things with it. Sort of like a magic wand. Perhaps it first identifies you, and then it can be used to make this happen, make others (maybe a server) do things for you. Also, just like a wand, it can be passed around. So it must have some memory or state of who or how it was charmed. This is all just guess work though, from what we see here.

With not much of a prior introduction to it and not knowing where it came from, I wandered around this place that is the openstacksdk trying to find more about it. You see, I was supposed to implement a feature at this place and to do so, I needed to use this session to get some things done. I wanted to get to know all about this session first Who it was, what does it do. But alas, my search failed. I didn't find a more detailed description nearby. Tracing back, following it, through the signs it left, I saw it invoked like this.

from keystoneauth1 import adapter
from keystoneauth1 import session as ks_session

It was always summoned, not a native of this place (openstacksdk) but brought in from outside. So I didn't find anyone having detailed information about this session. It was one mysterious keystone. I was dismayed, I had to use it. How would I, if I didn't know who it was, or know how to talk to it?

I was saddened, I was stuck. I was scared of not progressing, and almost fell into a rut.

My mentor fortunately noticed, and helped me out, they pointed me at examples, encouraging me, to figure it out.

Here is one such example

    def list_vifs(self, session):
        """List IDs of VIFs attached to the node.

        The exact form of the VIF ID depends on the network interface used by
        the node. In the most common case it is a Network service port
        (NOT a Bare Metal port) ID.

        :param session: The session to use for making this request.
        :type session: :class:`~keystoneauth1.adapter.Adapter`
        :return: List of VIF IDs as strings.
        :raises: :exc:`~openstack.exceptions.NotSupported` if the server
            does not support the VIF API.
        session = self._get_session(session)
        version = self._assert_microversion_for(
            session, 'fetch', _common.VIF_VERSION,
            error_message=("Cannot use VIF attachment API"))

        request = self._prepare_request(requires_id=True)
        request.url = utils.urljoin(request.url, 'vifs')
        response = session.get(
            request.url, headers=request.headers, microversion=version)

        msg = ("Failed to list VIFs attached to bare metal node {node}"
        exceptions.raise_from_response(response, error_message=msg)
        return [vif['id'] for vif in response.json()['vifs']]

Looking close, ignoring the rest, we can focus on the session object and see how it behaves, try to glean how it's used.

session = self._get_session(session)
# Just by looking we can guess, perhaps this session is being refreshed to it's current state, or perhaps minorly transformed from a generic form into a form we can use. 
# And indeed looking at it's source, indicates the latter

response = session.get(
            request.url, headers=request.headers, microversion=version)

# Ignore the microversion for now. But if you know basic http, looks like what's happening is a get request is being initiated at the url, and the returned response is being saved.
# For some magicians it would be natural to just wave this s̶p̶e̶l̶l̶ fuction of session at any url and hope it works.
# Some even more daring would probably even try `session.put( ... ) ` or session.delete( ... ) and expect it to work*. 
# Some would be too distracted by this strange microversion and hesitate to touch the function until they know more, fearing side effects. (like I was at first :p)

# * (GET, PUT, POST, DELETE being some classic HTTP request methods)

Browsing through the code, I did find some other incantations. Like:

        response = session.put(
            request.url, json=body,
            headers=request.headers, microversion=version,

        response =
            request.url, json=body,
            headers=request.headers, microversion=version,

        response = session.delete(
            request.url, headers=request.headers, microversion=version,

I tried these incantations myself (skipping the extra parameters). And it did seem to work. So it does seem like an interface to HTTP methods. This session wand allows you to call HTTP methods. You can pass it the url, headers and json body in case of post/put request and it seemingly does the job. How it works is magic (a black box). What else it does, is also a mystery.

For my purpose, this was all I needed from our mysterious session. And so we parted ways. Until we met again, another place.

I hadn't seen fine details of our session. Didn't know where exactly they were from. Hadn't seen how session was created, haven't read about their usage or detailed description in a document. And that felt blinding.

But, just by observing someone's behaviour, seeing how others call them, how they react to those calls, you can sometimes glean enough about an entity (Perhaps even a person).. Enough to work with them.

Who they are may remain a mystery, and you may never get to know, as much as you'd like. But's that's okay. You don't have to always.