Re: Creating decorator that modifies _cp_dispatch
Sviatoslav Sydorenko <[email protected]> Sun, 28 Jul 2019 22:36:15 +0200
| Newsgroups | gmane.comp.python.cherrypy |
|---|---|
| Message-ID | <CAFYONRDjh4AWFNeGN81eUZEb8mMV21KrFJ+C+y=42xUnMC=ckQ@mail.gmail.com> |
--000000000000ce69c4058ec3ba84
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
Try logging args/kwargs in your wrapper:
+ print(args)
+ print(kwargs)
kwargs =3D dict(zip(keys,args))
But I have another question now: why do you need _cp_dispatch there? What's
your end-goal? It seems like you're just looking to reimplement the default
method with a regular URI traversal based dispatcher.
I've made a small demo for you. Is this what you're looking for?
$ cat cp_default_handler_demo.py
#! /usr/bin/env python
"""Demo of how to use the ``default`` handler method."""
import cherrypy
class HelloWorld:
"""Collection of traversed URL handlers."""
@cherrypy.expose
def index(self, **params): # pylint: disable=3Dno-self-use
"""Root URI HTTP handler."""
return f'Hello from index, see params: {params}'
@cherrypy.expose
def foo(self, **params): # pylint: disable=3Dno-self-use
"""Foo URI HTTP handler."""
return f"""
Hello from foo, see params: {params};<br>
cp params: {cherrypy.request.params}
"""
@cherrypy.expose
# pylint: disable=3Dno-self-use
def default(self, one, two=3DNone, three=3DNone, **params):
"""Default URI HTTP handler."""
return f"""
Hello from default, see params: {params};<br>
cp params: {cherrypy.request.params}<br>
one=3D{one}; two=3D{two}; three=3D{three}
"""
cherrypy.config.update({
'server.socket_port': 33333,
})
# pylint: disable=3Dexpression-not-assigned
__name__ =3D=3D '__main__' and cherrypy.quickstart(HelloWorld(), '/', {})
$ ./cp_default_handler_demo.py
[28/Jul/2019:22:30:05] ENGINE Listening for SIGTERM.
[28/Jul/2019:22:30:05] ENGINE Listening for SIGHUP.
[28/Jul/2019:22:30:05] ENGINE Listening for SIGUSR1.
[28/Jul/2019:22:30:05] ENGINE Bus STARTING
CherryPy Checker:
The Application mounted at '' has an empty config.
[28/Jul/2019:22:30:05] ENGINE Started monitor thread 'Autoreloader'.
[28/Jul/2019:22:30:05] ENGINE Serving on http://127.0.0.1:33333
[28/Jul/2019:22:30:05] ENGINE Bus STARTED
127.0.0.1 - - [28/Jul/2019:22:30:13] "GET / HTTP/1.1" 200 32 ""
"curl/7.65.1"
127.0.0.1 - - [28/Jul/2019:22:30:20] "GET / HTTP/1.1" 200 32 ""
"curl/7.65.1"
127.0.0.1 - - [28/Jul/2019:22:30:29] "GET /?x=3Dy HTTP/1.1" 200 40 ""
"curl/7.65.1"
127.0.0.1 - - [28/Jul/2019:22:30:40] "GET /foo HTTP/1.1" 200 83 ""
"curl/7.65.1"
127.0.0.1 - - [28/Jul/2019:22:30:44] "GET /foo?x=3Dy HTTP/1.1" 200 99 ""
"curl/7.65.1"
127.0.0.1 - - [28/Jul/2019:22:31:20] "GET /o/t/tt?hoho=3Dwow HTTP/1.1" 200
152 "" "curl/7.65.1"
^C[28/Jul/2019:22:31:32] ENGINE Keyboard Interrupt: shutting down bus
[28/Jul/2019:22:31:32] ENGINE Bus STOPPING
[28/Jul/2019:22:31:32] ENGINE HTTP Server
cherrypy._cpwsgi_server.CPWSGIServer(('127.0.0.1', 33333)) shut down
[28/Jul/2019:22:31:32] ENGINE Stopped thread 'Autoreloader'.
[28/Jul/2019:22:31:32] ENGINE Bus STOPPED
[28/Jul/2019:22:31:32] ENGINE Bus EXITING
[28/Jul/2019:22:31:32] ENGINE Bus EXITED
[28/Jul/2019:22:31:32] ENGINE Waiting for child threads to terminate...
$ curl http://127.0.0.1:33333
Hello from index, see params: {}
$ curl http://127.0.0.1:33333/\?x\=3Dy
Hello from index, see params: {'x': 'y'}
$ curl http://127.0.0.1:33333/foo
Hello from foo, see params: {};<br>
cp params: {}
$ curl http://127.0.0.1:33333/foo\?x\=3Dy
=D0=BD=D0=B4, 28 =D0=BB=D0=B8=D0=BF. 2019 =D0=BE 11:50 Adam Baxter <voltage=
[email protected]> =D0=BF=D0=B8=D1=88=D0=B5:
> Getting closer:
>
> def from_path(*keys):
> def decorator(http_handler):
> def handler_wrapper(*args, **kwargs):
> kwargs =3D dict(zip(keys,args))
> return http_handler(args[0], **kwargs)
> return handler_wrapper
> return decorator
>
> class HelloWorld(object):
> def _cp_dispatch(self, vpath):
> print("dispatching " + repr(vpath))
> return self.index
>
> @cherrypy.expose('/')
> @from_path('one','two','three')
> def index(self, **kwargs):
> return f"My kwargs were {kwargs}"
>
> cherrypy.quickstart(HelloWorld())
>
> If I GET /a/b/c, the server responds with:
> My kwargs were {'one': <__main__.HelloWorld object at 0x7f45622dd860>,
> 'two': 'b', 'three': 'c'}
>
> I am unsure what's eating the first path segment there.
>
> I would like to implement something similar to the way ASP.NET does
> attribute-based routing but I'm not sure how much further I'll get. It's
> been an interesting dive into CherryPy at the least.
>
> --
> You received this message because you are subscribed to the Google Groups
> "cherrypy-users" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to cherrypy-users+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/[email protected]
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/cherrypy-users/40055517-97e3-482b-abe0-=
ea329ea55f45%40googlegroups.com
> <https://groups.google.com/d/msgid/cherrypy-users/40055517-97e3-482b-abe0=
-ea329ea55f45%40googlegroups.com?utm_medium=3Demail&utm_source=3Dfooter>
> .
>
--=20
Cheers,
Sviatoslav.
--=20
You received this message because you are subscribed to the Google Groups "=
cherrypy-users" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to cherrypy-users+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/[email protected]
To view this discussion on the web visit https://groups.google.com/d/msgid/=
cherrypy-users/CAFYONRDjh4AWFNeGN81eUZEb8mMV21KrFJ%2BC%2By%3D42xUnMC%3DckQ%=
40mail.gmail.com.
--000000000000ce69c4058ec3ba84
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">Try logging args/kwargs in your wrapper:<div><br></div><di=
v><span style=3D"font-family:"courier new",monospace">+ print(arg=
s)</span><br></div><div><span style=3D"font-family:"courier new",=
monospace">+ print(kwargs)</span><span style=3D"font-family:"courier n=
ew",monospace"><br></span></div><div><span style=3D"font-family:"=
courier new",monospace">=C2=A0 kwargs =3D dict(zip(keys,args))</span><=
br></div><div><span style=3D"font-family:"courier new",monospace"=
><br></span></div><div><span style=3D"font-family:"courier new",m=
onospace">But I have another question now: why do you need=C2=A0</span><fon=
t face=3D"courier new, monospace">_cp_dispatch</font><span style=3D"font-fa=
mily:"courier new",monospace"> there? What's your end-goal? I=
t seems like you're just looking to reimplement the default method with=
a regular URI traversal based dispatcher.</span></div><div><span style=3D"=
font-family:"courier new",monospace"><br></span></div><div><span =
style=3D"font-family:"courier new",monospace">I've made a sma=
ll demo for you. Is this what you're looking for?</span></div><div><spa=
n style=3D"font-family:"courier new",monospace"><br></span></div>=
<div><font face=3D"courier new, monospace">$ cat cp_default_handler_demo.py=
<br>#! /usr/bin/env python<br>"""Demo of how to use the ``de=
fault`` handler method."""<br><br>import cherrypy<br><br><br=
>class HelloWorld:<br>=C2=A0 =C2=A0 """Collection of travers=
ed URL handlers."""<br><br>=C2=A0 =C2=A0 @cherrypy.expose<br=
>=C2=A0 =C2=A0 def index(self, **params): =C2=A0# pylint: disable=3Dno-self=
-use<br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 """Root URI HTTP handler=
."""<br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 return f'Hello from =
index, see params: {params}'<br><br>=C2=A0 =C2=A0 @cherrypy.expose<br>=
=C2=A0 =C2=A0 def foo(self, **params): =C2=A0# pylint: disable=3Dno-self-us=
e<br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 """Foo URI HTTP handler.&qu=
ot;""<br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 return f"""<b=
r>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 Hello from foo, see params: {pa=
rams};<br><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 cp params: {c=
herrypy.request.params}<br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 """<b=
r><br>=C2=A0 =C2=A0 @cherrypy.expose<br>=C2=A0 =C2=A0 # pylint: disable=3Dn=
o-self-use<br>=C2=A0 =C2=A0 def default(self, one, two=3DNone, three=3DNone=
, **params):<br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 """Default URI H=
TTP handler."""<br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 return f"=
;""<br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 Hello from defau=
lt, see params: {params};<br><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
=C2=A0 cp params: {cherrypy.request.params}<br><br>=C2=A0 =C2=A0 =C2=
=A0 =C2=A0 =C2=A0 =C2=A0 one=3D{one}; two=3D{two}; three=3D{three}<br>=C2=
=A0 =C2=A0 =C2=A0 =C2=A0 """<br><br><br>cherrypy.config.upda=
te({<br>=C2=A0 =C2=A0 'server.socket_port': 33333,<br>})<br># pylin=
t: disable=3Dexpression-not-assigned<br>__name__ =3D=3D '__main__' =
and cherrypy.quickstart(HelloWorld(), '/', {})<br></font></div><div=
><font face=3D"courier new, monospace"><br></font></div><div><font face=3D"=
courier new, monospace">$ ./cp_default_handler_demo.py<br>[28/Jul/2019:22:3=
0:05] ENGINE Listening for SIGTERM.<br>[28/Jul/2019:22:30:05] ENGINE Listen=
ing for SIGHUP.<br>[28/Jul/2019:22:30:05] ENGINE Listening for SIGUSR1.<br>=
[28/Jul/2019:22:30:05] ENGINE Bus STARTING<br>CherryPy Checker:<br>The Appl=
ication mounted at '' has an empty config.<br><br>[28/Jul/2019:22:3=
0:05] ENGINE Started monitor thread 'Autoreloader'.<br>[28/Jul/2019=
:22:30:05] ENGINE Serving on <a href=3D"http://127.0.0.1:33333">http://127.=
0.0.1:33333</a><br>[28/Jul/2019:22:30:05] ENGINE Bus STARTED<br>127.0.0.1 -=
- [28/Jul/2019:22:30:13] "GET / HTTP/1.1" 200 32 "" &q=
uot;curl/7.65.1"<br>127.0.0.1 - - [28/Jul/2019:22:30:20] "GET / H=
TTP/1.1" 200 32 "" "curl/7.65.1"<br>127.0.0.1 - - =
[28/Jul/2019:22:30:29] "GET /?x=3Dy HTTP/1.1" 200 40 ""=
"curl/7.65.1"<br>127.0.0.1 - - [28/Jul/2019:22:30:40] "GET =
/foo HTTP/1.1" 200 83 "" "curl/7.65.1"<br>127.0.0.=
1 - - [28/Jul/2019:22:30:44] "GET /foo?x=3Dy HTTP/1.1" 200 99 &qu=
ot;" "curl/7.65.1"<br>127.0.0.1 - - [28/Jul/2019:22:31:20] &=
quot;GET /o/t/tt?hoho=3Dwow HTTP/1.1" 200 152 "" "curl/=
7.65.1"<br>^C[28/Jul/2019:22:31:32] ENGINE Keyboard Interrupt: shuttin=
g down bus<br>[28/Jul/2019:22:31:32] ENGINE Bus STOPPING<br>[28/Jul/2019:22=
:31:32] ENGINE HTTP Server cherrypy._cpwsgi_server.CPWSGIServer(('127.0=
.0.1', 33333)) shut down<br>[28/Jul/2019:22:31:32] ENGINE Stopped threa=
d 'Autoreloader'.<br>[28/Jul/2019:22:31:32] ENGINE Bus STOPPED<br>[=
28/Jul/2019:22:31:32] ENGINE Bus EXITING<br>[28/Jul/2019:22:31:32] ENGINE B=
us EXITED<br>[28/Jul/2019:22:31:32] ENGINE Waiting for child threads to ter=
minate...<br></font></div><div><font face=3D"courier new, monospace"><br></=
font></div><div><font face=3D"courier new, monospace">$ curl <a href=3D"htt=
p://127.0.0.1:33333">http://127.0.0.1:33333</a><br>Hello from index, see pa=
rams: {}<br>$ curl <a href=3D"http://127.0.0.1:33333/\?x\=3Dy">http://127.0=
.0.1:33333/\?x\=3Dy</a><br>Hello from index, see params: {'x': '=
;y'}<br>$ curl <a href=3D"http://127.0.0.1:33333/foo">http://127.0.0.1:=
33333/foo</a><br><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 Hello from f=
oo, see params: {};<br><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
cp params: {}<br>=C2=A0 =C2=A0 =C2=A0 =C2=A0=C2=A0<br>$ curl <a href=3D"htt=
p://127.0.0.1:33333/foo\?x\=3Dy">http://127.0.0.1:33333/foo\?x\=3Dy</a></fo=
nt><br></div></div><br><div class=3D"gmail_quote"><div dir=3D"ltr" class=3D=
"gmail_attr">=D0=BD=D0=B4, 28 =D0=BB=D0=B8=D0=BF. 2019 =D0=BE 11:50 Adam Ba=
xter <<a href=3D"mailto:[email protected]">[email protected]</a>=
> =D0=BF=D0=B8=D1=88=D0=B5:<br></div><blockquote class=3D"gmail_quote" s=
tyle=3D"margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);pad=
ding-left:1ex"><div dir=3D"ltr"><div>Getting closer:</div><div><span style=
=3D"font-family:"courier new",monospace"><br></span></div><div><s=
pan style=3D"font-family:"courier new",monospace">def from_path(*=
keys):<br>=C2=A0=C2=A0=C2=A0 def decorator(http_handler):<br>=C2=A0=C2=A0=
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 def handler_wrapper(*args, **kwargs):<br>=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 kwargs =3D =
dict(zip(keys,args))<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0 return http_handler(args[0], **kwargs) <br>=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0 return handler_wrapper<br>=C2=A0=C2=A0=C2=A0 re=
turn decorator<br><br>class HelloWorld(object):<br>=C2=A0=C2=A0=C2=A0 def _=
cp_dispatch(self, vpath):<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 pri=
nt("dispatching " + repr(vpath))<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0 return self.index<br>=C2=A0=C2=A0=C2=A0 <br>=C2=A0=C2=A0=C2=
=A0 @cherrypy.expose('/')<br>=C2=A0=C2=A0=C2=A0 @from_path('one=
','two','three')<br>=C2=A0=C2=A0=C2=A0 def index(self, =
**kwargs):<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 return f"My k=
wargs were {kwargs}"<br>=C2=A0=C2=A0=C2=A0 <br>cherrypy.quickstart(Hel=
loWorld())</span><br></div><div><br></div><div>If I GET /a/b/c, the server =
responds with:</div><div>My kwargs were {'one': <__main__.HelloW=
orld object at 0x7f45622dd860>, 'two': 'b', 'three&#=
39;: 'c'}</div><div><br></div><div>I am unsure what's eating th=
e first path segment there.</div><div><br></div><div>I would like to implem=
ent something similar to the way <a href=3D"http://ASP.NET" target=3D"_blan=
k">ASP.NET</a> does attribute-based routing but I'm not sure how much f=
urther I'll get. It's been an interesting dive into CherryPy at the=
least.<br></div><div><br></div></div>
<p></p>
-- <br>
You received this message because you are subscribed to the Google Groups &=
quot;cherrypy-users" group.<br>
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:cherrypy-users+unsubscribe-/[email protected]" targ=
et=3D"_blank">cherrypy-users+unsubscribe-/[email protected]</a>.<br>
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/d/msgid/cherrypy-users/40055517-97e3-482b-abe0-ea329ea55f45%40googlegrou=
ps.com?utm_medium=3Demail&utm_source=3Dfooter" target=3D"_blank">https:=
//groups.google.com/d/msgid/cherrypy-users/40055517-97e3-482b-abe0-ea329ea5=
5f45%40googlegroups.com</a>.<br>
</blockquote></div><br clear=3D"all"><div><br></div>-- <br><div dir=3D"ltr"=
class=3D"gmail_signature"><div dir=3D"ltr">Cheers,<div>Sviatoslav.</div></=
div></div>
<p></p>
-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;cherrypy-users" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:cherrypy-users+unsubscribe-/[email protected]">cher=
rypy-users+unsubscribe-/[email protected]</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/d/msgid/cherrypy-users/CAFYONRDjh4AWFNeGN81eUZEb8mMV21KrFJ%2BC%2By%3D42x=
UnMC%3DckQ%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfooter">https:/=
/groups.google.com/d/msgid/cherrypy-users/CAFYONRDjh4AWFNeGN81eUZEb8mMV21Kr=
FJ%2BC%2By%3D42xUnMC%3DckQ%40mail.gmail.com</a>.<br />
--000000000000ce69c4058ec3ba84--