Using ServiceRpcProxy from Flask - best practices for dealing with connections?

Hi there,

I'm trying to create what is essentially an API gateway: an HTTP API that
external clients consume, which internally coordinates / interacts with
Nameko services. In other words, I'm looking for guidance on how to connect
to Nameko services from non-Nameko components (specifically, from a Flask
route).

This example gist
<https://gist.github.com/mattbennett/4250ce5d56b36a99bc39#file-app-py-L56-L61>
demonstrates how to use ServiceRpcProxy to connect to Nameko services,
which works like a charm. However, the comment in the gist suggests that "a
more intelligent solution would be a thread-local or a pool of shared
proxies," presumably since creating new connections per request is
expensive.

Does anyone have experience with using either the thread-local or
connection pool approach in production? If so, could you possibly point me
in the right direction in terms of implementation?

Mark

Hi Mark,

The gist you reference was actually part of a stack overflow question
<http://stackoverflow.com/questions/30002559/how-can-i-combine-flask-and-nameko>
specifically about using Flask and Nameko together. I answered the question
that was asked, but actually using Flask and Nameko together is an unusual
choice.

The http components
<http://nameko.readthedocs.io/en/stable/built_in_extensions.html#http-get-post>
of nameko are built on top of werkzeug, the same library that underpins
Flask. Our docs are a little misleading in only mentioning GET and POST,
because you can do everything werkzeug supports. In fact the http
entrypoint has basically the same interface as a flask route.

So for your API gateway I'd suggest using nameko directly. It doesn't
support templates, static files or sessions, but I'm guessing you won't
need those.

If you decide to use Flask, the comment about connection pools relates to
the fact that in that naive implementation you create a connection to the
broker every time you use it. That's very expensive. I don't know enough
about Flask to implement it elegantly, but there should be a way to create
a pool of proxies somewhere and then check one out for each request.

Hope that helps.

Matt.

···

On Wednesday, July 6, 2016 at 10:57:12 PM UTC+1, Mark Hudnall wrote:

Hi there,

I'm trying to create what is essentially an API gateway: an HTTP API that
external clients consume, which internally coordinates / interacts with
Nameko services. In other words, I'm looking for guidance on how to connect
to Nameko services from non-Nameko components (specifically, from a Flask
route).

This example gist
<https://www.google.com/url?q=https%3A%2F%2Fgist.github.com%2Fmattbennett%2F4250ce5d56b36a99bc39%23file-app-py-L56-L61&sa=D&sntz=1&usg=AFQjCNGj_8YmdvzDL-hObX9q7AjDm0ZrHg>
demonstrates how to use ServiceRpcProxy to connect to Nameko services,
which works like a charm. However, the comment in the gist suggests that "a
more intelligent solution would be a thread-local or a pool of shared
proxies," presumably since creating new connections per request is
expensive.

Does anyone have experience with using either the thread-local or
connection pool approach in production? If so, could you possibly point me
in the right direction in terms of implementation?

Mark

Hi Matt, that makes sense.

I'm familiar with running Flask behind uWSGI and nginx in production --
does it make sense to use uWSGI in the context of Nameko's HTTP extension?

Mark

···

On Sunday, July 10, 2016 at 12:38:05 PM UTC-7, Matt Bennett wrote:

Hi Mark,

The gist you reference was actually part of a stack overflow question
<http://stackoverflow.com/questions/30002559/how-can-i-combine-flask-and-nameko>
specifically about using Flask and Nameko together. I answered the question
that was asked, but actually using Flask and Nameko together is an unusual
choice.

The http components
<http://nameko.readthedocs.io/en/stable/built_in_extensions.html#http-get-post>
of nameko are built on top of werkzeug, the same library that underpins
Flask. Our docs are a little misleading in only mentioning GET and POST,
because you can do everything werkzeug supports. In fact the http
entrypoint has basically the same interface as a flask route.

So for your API gateway I'd suggest using nameko directly. It doesn't
support templates, static files or sessions, but I'm guessing you won't
need those.

If you decide to use Flask, the comment about connection pools relates to
the fact that in that naive implementation you create a connection to the
broker every time you use it. That's very expensive. I don't know enough
about Flask to implement it elegantly, but there should be a way to create
a pool of proxies somewhere and then check one out for each request.

Hope that helps.

Matt.

On Wednesday, July 6, 2016 at 10:57:12 PM UTC+1, Mark Hudnall wrote:

Hi there,

I'm trying to create what is essentially an API gateway: an HTTP API that
external clients consume, which internally coordinates / interacts with
Nameko services. In other words, I'm looking for guidance on how to connect
to Nameko services from non-Nameko components (specifically, from a Flask
route).

This example gist
<https://www.google.com/url?q=https%3A%2F%2Fgist.github.com%2Fmattbennett%2F4250ce5d56b36a99bc39%23file-app-py-L56-L61&sa=D&sntz=1&usg=AFQjCNGj_8YmdvzDL-hObX9q7AjDm0ZrHg>
demonstrates how to use ServiceRpcProxy to connect to Nameko services,
which works like a charm. However, the comment in the gist suggests that "a
more intelligent solution would be a thread-local or a pool of shared
proxies," presumably since creating new connections per request is
expensive.

Does anyone have experience with using either the thread-local or
connection pool approach in production? If so, could you possibly point me
in the right direction in terms of implementation?

Mark

Due to the way nameko works, we need to control the life cycle of requests,
so not sure if it's possible to expose a wsgi app to serve with e.g. uwsgi.
However, the nameko web extension uses eventlet's wsgi server, which is
perfectly fine. (see e.g. http://nichol.as/benchmark-of-python-web-servers
for a (pretty old, 2010, but still) comparison of a bunch of python web
servers. As always with benchmarks, to be taken with a grain of salt but
eventlet performs perfectly well.

If i recall, we don't support ssl termination, so (just like with uwsgi)
you'd put nameko's web server behind e.g. an nginx proxy

Best,
David

···

On Monday, 11 July 2016 19:30:10 UTC+1, Mark Hudnall wrote:

Hi Matt, that makes sense.

I'm familiar with running Flask behind uWSGI and nginx in production --
does it make sense to use uWSGI in the context of Nameko's HTTP extension?

Mark

On Sunday, July 10, 2016 at 12:38:05 PM UTC-7, Matt Bennett wrote:

Hi Mark,

The gist you reference was actually part of a stack overflow question
<http://stackoverflow.com/questions/30002559/how-can-i-combine-flask-and-nameko>
specifically about using Flask and Nameko together. I answered the question
that was asked, but actually using Flask and Nameko together is an unusual
choice.

The http components
<http://nameko.readthedocs.io/en/stable/built_in_extensions.html#http-get-post>
of nameko are built on top of werkzeug, the same library that underpins
Flask. Our docs are a little misleading in only mentioning GET and POST,
because you can do everything werkzeug supports. In fact the http
entrypoint has basically the same interface as a flask route.

So for your API gateway I'd suggest using nameko directly. It doesn't
support templates, static files or sessions, but I'm guessing you won't
need those.

If you decide to use Flask, the comment about connection pools relates to
the fact that in that naive implementation you create a connection to the
broker every time you use it. That's very expensive. I don't know enough
about Flask to implement it elegantly, but there should be a way to create
a pool of proxies somewhere and then check one out for each request.

Hope that helps.

Matt.

On Wednesday, July 6, 2016 at 10:57:12 PM UTC+1, Mark Hudnall wrote:

Hi there,

I'm trying to create what is essentially an API gateway: an HTTP API
that external clients consume, which internally coordinates / interacts
with Nameko services. In other words, I'm looking for guidance on how to
connect to Nameko services from non-Nameko components (specifically, from a
Flask route).

This example gist
<https://www.google.com/url?q=https%3A%2F%2Fgist.github.com%2Fmattbennett%2F4250ce5d56b36a99bc39%23file-app-py-L56-L61&sa=D&sntz=1&usg=AFQjCNGj_8YmdvzDL-hObX9q7AjDm0ZrHg>
demonstrates how to use ServiceRpcProxy to connect to Nameko services,
which works like a charm. However, the comment in the gist suggests that "a
more intelligent solution would be a thread-local or a pool of shared
proxies," presumably since creating new connections per request is
expensive.

Does anyone have experience with using either the thread-local or
connection pool approach in production? If so, could you possibly point me
in the right direction in terms of implementation?

Mark

Just wanted to circle back here - we ended up writing a *flask-nameko* wrapper
library to make working with Nameko and Flask easy. It's still early, but
would appreciate any and all feedback: https://github.com/clef/flask-nameko.

Cheers,
Jesse

···

On Tuesday, July 12, 2016 at 4:20:01 AM UTC-7, David Szotten wrote:

Due to the way nameko works, we need to control the life cycle of
requests, so not sure if it's possible to expose a wsgi app to serve with
e.g. uwsgi. However, the nameko web extension uses eventlet's wsgi server,
which is perfectly fine. (see e.g.
http://nichol.as/benchmark-of-python-web-servers for a (pretty old, 2010,
but still) comparison of a bunch of python web servers. As always with
benchmarks, to be taken with a grain of salt but eventlet performs
perfectly well.

If i recall, we don't support ssl termination, so (just like with uwsgi)
you'd put nameko's web server behind e.g. an nginx proxy

Best,
David

On Monday, 11 July 2016 19:30:10 UTC+1, Mark Hudnall wrote:

Hi Matt, that makes sense.

I'm familiar with running Flask behind uWSGI and nginx in production --
does it make sense to use uWSGI in the context of Nameko's HTTP extension?

Mark

On Sunday, July 10, 2016 at 12:38:05 PM UTC-7, Matt Bennett wrote:

Hi Mark,

The gist you reference was actually part of a stack overflow question
<http://stackoverflow.com/questions/30002559/how-can-i-combine-flask-and-nameko>
specifically about using Flask and Nameko together. I answered the question
that was asked, but actually using Flask and Nameko together is an unusual
choice.

The http components
<http://nameko.readthedocs.io/en/stable/built_in_extensions.html#http-get-post>
of nameko are built on top of werkzeug, the same library that underpins
Flask. Our docs are a little misleading in only mentioning GET and POST,
because you can do everything werkzeug supports. In fact the http
entrypoint has basically the same interface as a flask route.

So for your API gateway I'd suggest using nameko directly. It doesn't
support templates, static files or sessions, but I'm guessing you won't
need those.

If you decide to use Flask, the comment about connection pools relates
to the fact that in that naive implementation you create a connection to
the broker every time you use it. That's very expensive. I don't know
enough about Flask to implement it elegantly, but there should be a way to
create a pool of proxies somewhere and then check one out for each request.

Hope that helps.

Matt.

On Wednesday, July 6, 2016 at 10:57:12 PM UTC+1, Mark Hudnall wrote:

Hi there,

I'm trying to create what is essentially an API gateway: an HTTP API
that external clients consume, which internally coordinates / interacts
with Nameko services. In other words, I'm looking for guidance on how to
connect to Nameko services from non-Nameko components (specifically, from a
Flask route).

This example gist
<https://www.google.com/url?q=https%3A%2F%2Fgist.github.com%2Fmattbennett%2F4250ce5d56b36a99bc39%23file-app-py-L56-L61&sa=D&sntz=1&usg=AFQjCNGj_8YmdvzDL-hObX9q7AjDm0ZrHg>
demonstrates how to use ServiceRpcProxy to connect to Nameko services,
which works like a charm. However, the comment in the gist suggests that "a
more intelligent solution would be a thread-local or a pool of shared
proxies," presumably since creating new connections per request is
expensive.

Does anyone have experience with using either the thread-local or
connection pool approach in production? If so, could you possibly point me
in the right direction in terms of implementation?

Mark

Awesome. Will have a look

Best,
David

···

On Thursday, 28 July 2016 23:37:56 UTC+1, je...@pollak.io wrote:

Just wanted to circle back here - we ended up writing a *flask-nameko* wrapper
library to make working with Nameko and Flask easy. It's still early, but
would appreciate any and all feedback:
https://github.com/clef/flask-nameko.

Cheers,
Jesse

On Tuesday, July 12, 2016 at 4:20:01 AM UTC-7, David Szotten wrote:

Due to the way nameko works, we need to control the life cycle of
requests, so not sure if it's possible to expose a wsgi app to serve with
e.g. uwsgi. However, the nameko web extension uses eventlet's wsgi server,
which is perfectly fine. (see e.g.
http://nichol.as/benchmark-of-python-web-servers for a (pretty old,
2010, but still) comparison of a bunch of python web servers. As always
with benchmarks, to be taken with a grain of salt but eventlet performs
perfectly well.

If i recall, we don't support ssl termination, so (just like with uwsgi)
you'd put nameko's web server behind e.g. an nginx proxy

Best,
David

On Monday, 11 July 2016 19:30:10 UTC+1, Mark Hudnall wrote:

Hi Matt, that makes sense.

I'm familiar with running Flask behind uWSGI and nginx in production --
does it make sense to use uWSGI in the context of Nameko's HTTP extension?

Mark

On Sunday, July 10, 2016 at 12:38:05 PM UTC-7, Matt Bennett wrote:

Hi Mark,

The gist you reference was actually part of a stack overflow question
<http://stackoverflow.com/questions/30002559/how-can-i-combine-flask-and-nameko>
specifically about using Flask and Nameko together. I answered the question
that was asked, but actually using Flask and Nameko together is an unusual
choice.

The http components
<http://nameko.readthedocs.io/en/stable/built_in_extensions.html#http-get-post>
of nameko are built on top of werkzeug, the same library that underpins
Flask. Our docs are a little misleading in only mentioning GET and POST,
because you can do everything werkzeug supports. In fact the http
entrypoint has basically the same interface as a flask route.

So for your API gateway I'd suggest using nameko directly. It doesn't
support templates, static files or sessions, but I'm guessing you won't
need those.

If you decide to use Flask, the comment about connection pools relates
to the fact that in that naive implementation you create a connection to
the broker every time you use it. That's very expensive. I don't know
enough about Flask to implement it elegantly, but there should be a way to
create a pool of proxies somewhere and then check one out for each request.

Hope that helps.

Matt.

On Wednesday, July 6, 2016 at 10:57:12 PM UTC+1, Mark Hudnall wrote:

Hi there,

I'm trying to create what is essentially an API gateway: an HTTP API
that external clients consume, which internally coordinates / interacts
with Nameko services. In other words, I'm looking for guidance on how to
connect to Nameko services from non-Nameko components (specifically, from a
Flask route).

This example gist
<https://www.google.com/url?q=https%3A%2F%2Fgist.github.com%2Fmattbennett%2F4250ce5d56b36a99bc39%23file-app-py-L56-L61&sa=D&sntz=1&usg=AFQjCNGj_8YmdvzDL-hObX9q7AjDm0ZrHg>
demonstrates how to use ServiceRpcProxy to connect to Nameko services,
which works like a charm. However, the comment in the gist suggests that "a
more intelligent solution would be a thread-local or a pool of shared
proxies," presumably since creating new connections per request is
expensive.

Does anyone have experience with using either the thread-local or
connection pool approach in production? If so, could you possibly point me
in the right direction in terms of implementation?

Mark