Skip to content

Commit f8e93ea

Browse files
committed
fixes #661
1 parent 04dd1d2 commit f8e93ea

File tree

3 files changed

+240
-1
lines changed

3 files changed

+240
-1
lines changed

fasthtml/_modidx.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,8 @@
153153
'fasthtml/oauth.py'),
154154
'fasthtml.oauth.Auth0AppClient.login_link': ( 'api/oauth.html#auth0appclient.login_link',
155155
'fasthtml/oauth.py'),
156+
'fasthtml.oauth.Credentials.save': ('api/oauth.html#credentials.save', 'fasthtml/oauth.py'),
157+
'fasthtml.oauth.Credentials.update': ('api/oauth.html#credentials.update', 'fasthtml/oauth.py'),
156158
'fasthtml.oauth.DiscordAppClient': ('api/oauth.html#discordappclient', 'fasthtml/oauth.py'),
157159
'fasthtml.oauth.DiscordAppClient.__init__': ( 'api/oauth.html#discordappclient.__init__',
158160
'fasthtml/oauth.py'),
@@ -164,6 +166,7 @@
164166
'fasthtml.oauth.GitHubAppClient.__init__': ('api/oauth.html#githubappclient.__init__', 'fasthtml/oauth.py'),
165167
'fasthtml.oauth.GoogleAppClient': ('api/oauth.html#googleappclient', 'fasthtml/oauth.py'),
166168
'fasthtml.oauth.GoogleAppClient.__init__': ('api/oauth.html#googleappclient.__init__', 'fasthtml/oauth.py'),
169+
'fasthtml.oauth.GoogleAppClient.creds': ('api/oauth.html#googleappclient.creds', 'fasthtml/oauth.py'),
167170
'fasthtml.oauth.GoogleAppClient.from_file': ( 'api/oauth.html#googleappclient.from_file',
168171
'fasthtml/oauth.py'),
169172
'fasthtml.oauth.HuggingFaceClient': ('api/oauth.html#huggingfaceclient', 'fasthtml/oauth.py'),
@@ -186,6 +189,7 @@
186189
'fasthtml/oauth.py'),
187190
'fasthtml.oauth._AppClient.retr_id': ('api/oauth.html#_appclient.retr_id', 'fasthtml/oauth.py'),
188191
'fasthtml.oauth._AppClient.retr_info': ('api/oauth.html#_appclient.retr_info', 'fasthtml/oauth.py'),
192+
'fasthtml.oauth.load_creds': ('api/oauth.html#load_creds', 'fasthtml/oauth.py'),
189193
'fasthtml.oauth.redir_url': ('api/oauth.html#redir_url', 'fasthtml/oauth.py'),
190194
'fasthtml.oauth.url_match': ('api/oauth.html#url_match', 'fasthtml/oauth.py')},
191195
'fasthtml.pico': { 'fasthtml.pico.Card': ('api/pico.html#card', 'fasthtml/pico.py'),

fasthtml/oauth.py

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
# %% auto 0
66
__all__ = ['http_patterns', 'GoogleAppClient', 'GitHubAppClient', 'HuggingFaceClient', 'DiscordAppClient', 'Auth0AppClient',
7-
'redir_url', 'url_match', 'OAuth']
7+
'redir_url', 'url_match', 'OAuth', 'load_creds']
88

99
# %% ../nbs/api/08_oauth.ipynb
1010
from .common import *
@@ -194,3 +194,37 @@ def login_link(self, req, scope=None, state=None): return self.cli.login_link(se
194194
def check_invalid(self, req, session, auth): return False
195195
def logout(self, session): return self.redir_login(session)
196196
def get_auth(self, info, ident, session, state): raise NotImplementedError()
197+
198+
# %% ../nbs/api/08_oauth.ipynb
199+
try:
200+
from google.oauth2.credentials import Credentials
201+
from google.auth.transport.requests import Request
202+
except ImportError:
203+
Request=None
204+
class Credentials: pass
205+
206+
# %% ../nbs/api/08_oauth.ipynb
207+
@patch
208+
def update(self:Credentials):
209+
"Refresh the credentials if they are expired, and return them"
210+
if self.expired: self.refresh(Request())
211+
return self
212+
213+
# %% ../nbs/api/08_oauth.ipynb
214+
@patch
215+
def save(self:Credentials, fname):
216+
"Save credentials to `fname`"
217+
save_pickle(fname, self)
218+
219+
# %% ../nbs/api/08_oauth.ipynb
220+
def load_creds(fname):
221+
"Load credentials from `fname`"
222+
return load_pickle(fname).update()
223+
224+
# %% ../nbs/api/08_oauth.ipynb
225+
@patch
226+
def creds(self:GoogleAppClient):
227+
"Create `Credentials` from the client, refreshing if needed"
228+
return Credentials(token=self.access_token, refresh_token=self.refresh_token,
229+
token_uri=self.token_url, client_id=self.client_id,
230+
client_secret=self.client_secret, scopes=self.scope).update()

nbs/api/08_oauth.ipynb

Lines changed: 201 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,17 @@
4444
"import secrets, httpx"
4545
]
4646
},
47+
{
48+
"cell_type": "code",
49+
"execution_count": null,
50+
"id": "b560f0c3",
51+
"metadata": {},
52+
"outputs": [],
53+
"source": [
54+
"#| hide\n",
55+
"from nbdev.showdoc import show_doc"
56+
]
57+
},
4758
{
4859
"cell_type": "code",
4960
"execution_count": null,
@@ -483,6 +494,196 @@
483494
" def get_auth(self, info, ident, session, state): raise NotImplementedError()"
484495
]
485496
},
497+
{
498+
"cell_type": "markdown",
499+
"id": "538de5d3",
500+
"metadata": {},
501+
"source": [
502+
"### Google helpers"
503+
]
504+
},
505+
{
506+
"cell_type": "code",
507+
"execution_count": null,
508+
"id": "be2990cf",
509+
"metadata": {},
510+
"outputs": [],
511+
"source": [
512+
"#| export\n",
513+
"try:\n",
514+
" from google.oauth2.credentials import Credentials\n",
515+
" from google.auth.transport.requests import Request\n",
516+
"except ImportError:\n",
517+
" Request=None\n",
518+
" class Credentials: pass"
519+
]
520+
},
521+
{
522+
"cell_type": "code",
523+
"execution_count": null,
524+
"id": "7393bc12",
525+
"metadata": {},
526+
"outputs": [],
527+
"source": [
528+
"#| export\n",
529+
"@patch\n",
530+
"def update(self:Credentials):\n",
531+
" \"Refresh the credentials if they are expired, and return them\"\n",
532+
" if self.expired: self.refresh(Request())\n",
533+
" return self"
534+
]
535+
},
536+
{
537+
"cell_type": "code",
538+
"execution_count": null,
539+
"id": "b68863e4",
540+
"metadata": {},
541+
"outputs": [
542+
{
543+
"data": {
544+
"text/markdown": [
545+
"---\n",
546+
"\n",
547+
"### Credentials.update\n",
548+
"\n",
549+
"> Credentials.update ()\n",
550+
"\n",
551+
"*Refresh the credentials if they are expired, and return them*"
552+
],
553+
"text/plain": [
554+
"---\n",
555+
"\n",
556+
"### Credentials.update\n",
557+
"\n",
558+
"> Credentials.update ()\n",
559+
"\n",
560+
"*Refresh the credentials if they are expired, and return them*"
561+
]
562+
},
563+
"execution_count": null,
564+
"metadata": {},
565+
"output_type": "execute_result"
566+
}
567+
],
568+
"source": [
569+
"show_doc(Credentials.update)"
570+
]
571+
},
572+
{
573+
"cell_type": "code",
574+
"execution_count": null,
575+
"id": "ace16168",
576+
"metadata": {},
577+
"outputs": [],
578+
"source": [
579+
"#| export\n",
580+
"@patch\n",
581+
"def save(self:Credentials, fname):\n",
582+
" \"Save credentials to `fname`\"\n",
583+
" save_pickle(fname, self)"
584+
]
585+
},
586+
{
587+
"cell_type": "code",
588+
"execution_count": null,
589+
"id": "877a7b20",
590+
"metadata": {},
591+
"outputs": [
592+
{
593+
"data": {
594+
"text/markdown": [
595+
"---\n",
596+
"\n",
597+
"### Credentials.save\n",
598+
"\n",
599+
"> Credentials.save (fname)\n",
600+
"\n",
601+
"*Save credentials to `fname`*"
602+
],
603+
"text/plain": [
604+
"---\n",
605+
"\n",
606+
"### Credentials.save\n",
607+
"\n",
608+
"> Credentials.save (fname)\n",
609+
"\n",
610+
"*Save credentials to `fname`*"
611+
]
612+
},
613+
"execution_count": null,
614+
"metadata": {},
615+
"output_type": "execute_result"
616+
}
617+
],
618+
"source": [
619+
"show_doc(Credentials.save)"
620+
]
621+
},
622+
{
623+
"cell_type": "code",
624+
"execution_count": null,
625+
"id": "5ef02a88",
626+
"metadata": {},
627+
"outputs": [],
628+
"source": [
629+
"#| export\n",
630+
"def load_creds(fname):\n",
631+
" \"Load credentials from `fname`\"\n",
632+
" return load_pickle(fname).update()"
633+
]
634+
},
635+
{
636+
"cell_type": "code",
637+
"execution_count": null,
638+
"id": "a0024ab0",
639+
"metadata": {},
640+
"outputs": [],
641+
"source": [
642+
"#| export\n",
643+
"@patch\n",
644+
"def creds(self:GoogleAppClient):\n",
645+
" \"Create `Credentials` from the client, refreshing if needed\"\n",
646+
" return Credentials(token=self.access_token, refresh_token=self.refresh_token, \n",
647+
" token_uri=self.token_url, client_id=self.client_id,\n",
648+
" client_secret=self.client_secret, scopes=self.scope).update()"
649+
]
650+
},
651+
{
652+
"cell_type": "code",
653+
"execution_count": null,
654+
"id": "8de24c61",
655+
"metadata": {},
656+
"outputs": [
657+
{
658+
"data": {
659+
"text/markdown": [
660+
"---\n",
661+
"\n",
662+
"### GoogleAppClient.creds\n",
663+
"\n",
664+
"> GoogleAppClient.creds ()\n",
665+
"\n",
666+
"*Create `Credentials` from the client, refreshing if needed*"
667+
],
668+
"text/plain": [
669+
"---\n",
670+
"\n",
671+
"### GoogleAppClient.creds\n",
672+
"\n",
673+
"> GoogleAppClient.creds ()\n",
674+
"\n",
675+
"*Create `Credentials` from the client, refreshing if needed*"
676+
]
677+
},
678+
"execution_count": null,
679+
"metadata": {},
680+
"output_type": "execute_result"
681+
}
682+
],
683+
"source": [
684+
"show_doc(GoogleAppClient.creds)"
685+
]
686+
},
486687
{
487688
"cell_type": "markdown",
488689
"id": "474e14b4",

0 commit comments

Comments
 (0)