Skip to content

Commit

Permalink
Add session parameter (#79)
Browse files Browse the repository at this point in the history
* Add session parameter to OneDriveFS

* Update README
  • Loading branch information
abichinger authored Sep 6, 2024
1 parent 1db3976 commit a172c00
Show file tree
Hide file tree
Showing 2 changed files with 72 additions and 14 deletions.
35 changes: 35 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ Implementation of pyfilesystem2 file system using OneDrive

# Usage

`fs.onedrivefs` can create a [`requests_oauthlib.OAuth2Session`](https://requests-oauthlib.readthedocs.io/en/latest/oauth2_workflow.html#) for you. This way the `OAuth2Session` is going to refresh the tokens for you.

``` python
onedriveFS = OneDriveFS(
clientId=<your client id>,
Expand All @@ -16,4 +18,37 @@ onedriveFS = OneDriveFS(
# onedriveFS is now a standard pyfilesystem2 file system
```

You can handle the tokens outside of the library by passing a [`requests.Session`](https://requests.readthedocs.io/en/latest/user/advanced/#session-objects).
Here is an example of a custom session using [MSAL Python](https://learn.microsoft.com/en-us/entra/msal/python/)

``` python
class MSALSession(OAuth2Session):
def __init__(self, client: msal.ClientApplication):
super().__init__()
self.client = client

def request(self, *args, **kwargs):
account = self.client.get_accounts()[0]
self.token = self.client.acquire_token_silent_with_error(
scopes=["Files.ReadWrite"], account=account
)

return super().request(*args, **kwargs)

client = msal.ConfidentialClientApplication(
client_id=<your client id>,
client_credential=<your client secret>,
authority=f"https://login.microsoftonline.com/<your tenant>",
token_cache=<your token cache>,
)

# Authentication flow to populate the token cache
# YOUR AUTHENTICATION FLOW

session = MSALSession(client=client)
onedriveFS = OneDriveFS(session=session)

# onedriveFS is now a standard pyfilesystem2 file system
```

Register your app [here](https://docs.microsoft.com/en-us/graph/auth-register-app-v2) to get a client ID and secret
51 changes: 37 additions & 14 deletions fs/onedrivefs/onedrivefs.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
from fs.path import basename, dirname
from fs.subfs import SubFS
from fs.time import datetime_to_epoch, epoch_to_datetime
from requests import codes, get
from requests import codes, get, Session
from requests_oauthlib import OAuth2Session

_log = getLogger(__name__)
Expand Down Expand Up @@ -155,10 +155,25 @@ def delete_subscription(self, id_):
def update_subscription(self, id_, expiration_date_time):
return self.delegate_fs().update_subscription(id_, expiration_date_time)

class OneDriveSession(OAuth2Session):
def __init__(self, *args, drive_root, **kwargs):
class OneDriveSession:
def __init__(self, drive_root, session: Session):
self._drive_root = drive_root
super().__init__(*args, **kwargs)
self.session = session

def get(self, *args, **kwargs):
return self.session.get(*args, **kwargs)

def post(self, *args, **kwargs):
return self.session.post(*args, **kwargs)

def patch(self, *args, **kwargs):
return self.session.patch(*args, **kwargs)

def put(self, *args, **kwargs):
return self.session.put(*args, **kwargs)

def delete(self, *args, **kwargs):
return self.session.delete(*args, **kwargs)

def path_url(self, path, extra):
# the path must start with '/'
Expand Down Expand Up @@ -199,20 +214,28 @@ class OneDriveFS(FS):
subfs_class = SubOneDriveFS
_service_root = 'https://graph.microsoft.com/v1.0'

def __init__(self, clientId, clientSecret, token, SaveToken, tenant='consumers', **kwargs):
def __init__(self, clientId=None, clientSecret=None, token=None, SaveToken=None, tenant='consumers', session=None, **kwargs):
super().__init__()

self.set_drive(**kwargs)
auto_refresh_kwargs = {'client_id': clientId}
if clientSecret is not None:
auto_refresh_kwargs['client_secret'] = clientSecret

if session is None:

auto_refresh_kwargs = {'client_id': clientId}
if clientSecret is not None:
auto_refresh_kwargs['client_secret'] = clientSecret

session = OAuth2Session(
client_id=clientId,
token=token,
auto_refresh_kwargs=auto_refresh_kwargs,
auto_refresh_url=f'https://login.microsoftonline.com/{tenant}/oauth2/v2.0/token',
token_updater=SaveToken,
)

self.session = OneDriveSession(
client_id=clientId,
token=token,
auto_refresh_kwargs=auto_refresh_kwargs,
auto_refresh_url=f'https://login.microsoftonline.com/{tenant}/oauth2/v2.0/token',
token_updater=SaveToken,
drive_root=self._drive_root
drive_root=self._drive_root,
session=session
)

self._meta = {
Expand Down

0 comments on commit a172c00

Please sign in to comment.