# `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](https://developer.mozilla.org/en-US/docs/Web/HTTP/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][1]. 

```
    #location: openstacksdk/openstack/baremetal/v1/node.py - 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). 
Also `commit` function 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`][2] 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}"
               .format(node=self.id))
        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,
            retriable_status_codes=_common.RETRIABLE_STATUS_CODES)

        response = session.post(
            request.url, json=body,
            headers=request.headers, microversion=version,
            retriable_status_codes=retriable_status_codes)

        response = session.delete(
            request.url, headers=request.headers, microversion=version,
            retriable_status_codes=_common.RETRIABLE_STATUS_CODES)
```

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.

[1]: https://github.com/openstack/openstacksdk/blob/9dc4a841145200583ac3f8c56df775a165e5f2f4/openstack/baremetal/v1/node.py#L314
[2]: https://github.com/openstack/openstacksdk

---

Comment?

You may find me on oftc going by cenne [irc-link]