pylons / pyramid_cookbook Goto Github PK
View Code? Open in Web Editor NEWPyramid cookbook recipes (documentation)
Home Page: https://docs.pylonsproject.org/projects/pyramid-cookbook/en/latest/
Pyramid cookbook recipes (documentation)
Home Page: https://docs.pylonsproject.org/projects/pyramid-cookbook/en/latest/
http://docs.pylonsproject.org/projects/pyramid_cookbook/en/latest/
Failed to load resource https://static.pylonsproject.org/fonts/nobile/stylesheet.css
Failed to load resource https://static.pylonsproject.org/fonts/neuton/stylesheet.css
I'm not sure where to look or what to change to fix this one.
I'm guessing there has been some change to asgi since this was written, however I lack the experience to figure it out on my own and submit a pr.
considering the time this was merged my guess would be that the example is not compatible with asgi 3.0. hoping the author @ERM might be able to offer some guidance on this.
https://docs.pylonsproject.org/projects/pyramid-cookbook/en/latest/deployment/asgi.html
original submission: #198
from asgiref.wsgi import WsgiToAsgi
from pyramid.config import Configurator
from pyramid.response import Response
class ExtendedWsgiToAsgi(WsgiToAsgi):
"""Extends the WsgiToAsgi wrapper to include an ASGI consumer protocol router"""
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.protocol_router = {"http": {}, "websocket": {}}
def __call__(self, scope, **kwargs):
protocol = scope["type"]
path = scope["path"]
try:
consumer = self.protocol_router[protocol][path]
except KeyError:
consumer = None
if consumer is not None:
return consumer(scope)
return super().__call__(scope, **kwargs)
def route(self, rule, *args, **kwargs):
try:
protocol = kwargs["protocol"]
except KeyError:
raise Exception("You must define a protocol type for an ASGI handler")
def _route(func):
self.protocol_router[protocol][rule] = func
return _route
HTML_BODY = """<!DOCTYPE html>
<html>
<head>
<title>ASGI WebSocket</title>
</head>
<body>
<h1>ASGI WebSocket Demo</h1>
<form action="" onsubmit="sendMessage(event)">
<input type="text" id="messageText" autocomplete="off"/>
<button>Send</button>
</form>
<ul id='messages'>
</ul>
<script>
var ws = new WebSocket("ws://127.0.0.1:8000/ws");
ws.onmessage = function(event) {
var messages = document.getElementById('messages')
var message = document.createElement('li')
var content = document.createTextNode(event.data)
message.appendChild(content)
messages.appendChild(message)
};
function sendMessage(event) {
var input = document.getElementById("messageText")
ws.send(input.value)
input.value = ''
event.preventDefault()
}
</script>
</body>
</html>
"""
# Define normal WSGI views
def hello_world(request):
return Response(HTML_BODY)
# Configure a normal WSGI app then wrap it with WSGI -> ASGI class
with Configurator() as config:
config.add_route("hello", "/")
config.add_view(hello_world, route_name="hello")
wsgi_app = config.make_wsgi_app()
app = ExtendedWsgiToAsgi(wsgi_app)
# Define ASGI consumers
@app.route("/ws", protocol="websocket")
def hello_websocket(scope):
async def asgi_instance(receive, send):
while True:
message = await receive()
if message["type"] == "websocket.connect":
await send({"type": "websocket.accept"})
if message["type"] == "websocket.receive":
text = message.get("text")
if text:
await send({"type": "websocket.send", "text": text})
else:
await send({"type": "websocket.send", "bytes": message.get("bytes")})
return asgi_instance
tom@tom-ThinkPad-P1:~/projects/navigator8_env$ pipenv run uvicorn websocket:app
Courtesy Notice: Pipenv found itself running within a virtual environment, so it will automatically use
that environment, instead of creating its own for any project. You can set PIPENV_IGNORE_VIRTUALENVS=1 t
o force pipenv to ignore that environment and create its own instead. You can set PIPENV_VERBOSITY=-1 to
suppress this warning.
INFO: Started server process [28427]
INFO: Waiting for application startup.
INFO: ASGI 'lifespan' protocol appears unsupported.
INFO: Application startup complete.
INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
ERROR: Exception in ASGI application
Traceback (most recent call last):
File "/home/tom/projects/navigator8_env/.venv/lib/python3.7/site-packages/uvicorn/protocols/http/httpt
ools_impl.py", line 385, in run_asgi
result = await app(self.scope, self.receive, self.send)
File "/home/tom/projects/navigator8_env/.venv/lib/python3.7/site-packages/uvicorn/middleware/proxy_hea
ders.py", line 45, in __call__
return await self.app(scope, receive, send)
File "/home/tom/projects/navigator8_env/.venv/lib/python3.7/site-packages/uvicorn/middleware/asgi2.py"
, line 6, in __call__
instance = self.app(scope)
File "./websocket.py", line 24, in __call__
return super().__call__(scope, **kwargs)
TypeError: __call__() missing 2 required positional arguments: 'receive' and 'send'
INFO: 127.0.0.1:59952 - "GET / HTTP/1.1" 500 Internal Server Error
pinning asgiref==2.3.2 fixes things.
What's the reason for using wsgiapp2 over wsgiapp in the WSGI porting example?
I found usage of wsgiapp2 a bit confusing, because it wasn't obvious to me that a route that was formerly at http://host/++namespace++/index.html
would become http://host/[literallyanything]/++namespace++/index.html
, whereas using wsgiapp it would remain the same as before. From how I see it, wsgiapp would be more useful than wsgiapp2 for porting an arbitrary WSGI app.
But to be fair, I'm trying to port Zope namespace traversal to Pyramid with very little knowledge of either, so maybe I'm just missing something.
Both tutorials mentioned here seem to no longer exist.
See Pylons/pyramid#2024 for example. Search for the terms "alchemy", "chameleon", and ".pt" to find candidates, then replace instances of the latter two with "jinja2" and ".jinja2".
This external recipe is good, except for the part about using SHA1 for passwords, so I put up a warning.
http://docs.pylonsproject.org/projects/pyramid-cookbook/en/latest/auth/akhet_sqlalchemy.html
Otherwise it's a good recipe.
If and when the external recipe is updated to a more secure method, then this warning my be removed.
There are currently two "Deploying Your Pyramid Application" sections in the cookbook.
The first comes from an all-in-one deployment.rst file.
The second comes from a broken-down version in the deployment directory.
Ben switched from the first to the second in 675e6b7 but a link to the first was added back in 3bdc7d2.
We should decide which one we want to keep!
http://docs.pylonsproject.org/projects/pyramid/1.3/tutorials/modwsgi/index.html
I am new to pyramid so if anyone could write something up quickly I would appreciate it and if not I will be playing around with deploying a simple app and will then make a write up and resubmit it to this issue.
thanks
Update this:
http://pyramid-cookbook.readthedocs.org/en/latest/templates/chameleon_i18n.html
to be compliant with this:
http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/i18n.html#working-with-gettext-translation-files
Report in IRC:
"when I run the extract_messages command I get "ValueError: Unknown extraction method 'lingua_python'", if I try changing it to just 'python' I get the same error for 'lingua_xml'"
There are no deployment instructions for people who want to deploy on Windows.
I will write some during the PyCon sprint for at least isapi-wsgi and reverse proxy to CherryPy based service.
Hi,
Following the instructions here:
https://github.com/Pylons/pyramid_cookbook/blob/master/contributing.md
In the Build HTML docs step, the build fails with a 404.
$ make html SPHINXBUILD=../../venv/bin/sphinx-build
../../venv/bin/sphinx-build -b html -d _build/doctrees -W . _build/html
Running Sphinx v7.2.6
making output directory... done
loading intersphinx inventory from https://docs.python.org/objects.inv...
loading intersphinx inventory from https://docs.python.org/3/objects.inv...
loading intersphinx inventory from https://docs.pylonsproject.org/projects/pyramid/en/latest/objects.inv...
loading intersphinx inventory from https://docs.pylonsproject.org/projects/pyramid-tutorials/en/latest/objects.inv...
intersphinx inventory has moved: https://docs.python.org/objects.inv -> https://docs.python.org/3/objects.inv
Warning, treated as error:
failed to reach any of the inventories with the following issues:
intersphinx inventory 'https://docs.pylonsproject.org/projects/pyramid-tutorials/en/latest/objects.inv' not fetchable due to <class 'requests.exceptions.HTTPError'>: 404 Client Error: Not Found for url: https://docs.pylonsproject.org/projects/pyramid-tutorials/en/latest/objects.inv
make: *** [Makefile:40: html] Error 2
Looks like the inventory url has moved to: https://docs.python.org/3/objects.inv
Hi,
Following the instructions here:
https://github.com/Pylons/pyramid_cookbook/blob/master/contributing.md
"Getting Started", step 5, produces:
$ venv/bin/pip install -e hack-on-cookbook/
...
Installing collected packages: snowballstemmer, pylons-sphinx-themes, zope.interface, urllib3, sphinxcontrib-serializinghtml, sphinxcontrib-qthelp, sphinxcontrib-jsmath, sphinxcontrib-htmlhelp, sphinxcontrib-devhelp, sphinxcontrib-applehelp, Pygments, packaging, MarkupSafe, imagesize, idna, docutils, charset-normalizer, certifi, babel, alabaster, requests, Jinja2, Sphinx, repoze.sphinx.autointerface, pyramid-cookbook
DEPRECATION: pylons-sphinx-themes is being installed using the legacy 'setup.py install' method, because it does not have a 'pyproject.toml' and the 'wheel' package is not installed. pip 23.1 will enforce this behaviour change. A possible replacement is to enable the '--use-pep517' option. Discussion can be found at https://github.com/pypa/pip/issues/8559
Running setup.py install for pylons-sphinx-themes ... done
...
I'm not sure if this is the right place to post this, but I am confused about a snippet from file_uploads.rst:
file_path = os.path.join('/tmp', '%s.mp3' % uuid.uuid4())
# We first write to a temporary file to prevent incomplete files from
# being used.
temp_file_path = file_path + '~'
output_file = open(temp_file_path, 'wb')
# Finally write the data to a temporary file
input_file.seek(0)
while True:
data = input_file.read(2<<16)
if not data:
break
output_file.write(data)
# If your data is really critical you may want to force it to disk first
# using output_file.flush(); os.fsync(output_file.fileno())
output_file.close()
# Now that we know the file has been fully saved to disk move it into place.
os.rename(temp_file_path, file_path)
First of all, I am not sure how this protects against saving incomplete files. If I make this change:
breakLoop = False
while True:
data = input_file.read(2<<16)
if not data or breakLoop:
break
output_file.write(data)
breakLoop = True
and say the file is bigger than 2<<16 bytes, it will still proceed on to the next chunk of code as it normally would, and it saves the incomplete file as file_path
. From the explanation in the rest of the document as well as the comments in the code, it would seem that this code is supposed to prevent that from happening.
And then another question - why are you doing this in a loop instead of just output_file.write(input_file.read())
?
I'm sure I'm missing something here, and any help would be much appreciated. Thanks!
I recently had cause to look into the licensing of code submitted to the cookbook, and have encountered a few issues which it would be good to address. In order of least to most (potentially) contentious:
It's not easy to find the license. The rendered documentation doesn't appear to include information on licensing, and there's no LICENSE
file in the repository.
What information there is on licensing isn't consistent. setup.py
says license="BSD-derived (http://www.repoze.org/LICENSE.txt)"
but CONTRIBUTORS.txt
has this paragraph:
Code committed to the Pyramid Cookbook source repository (Committed Code)
must be governed by the Creative Commons Attribution-Noncommercial-Share
Alike 3.0 United States License
(http://creativecommons.org/licenses/by-nc-sa/3.0/us/). Until Agendaless
Consulting declares in writing an acceptable license other than the by-nc-sa
3.0 license, only it shall be used. A list of exceptions is detailed within
the "Licensing Exceptions" section of this document, if one exists.
The license that I would have to assume from the above (CC BY-NC-SA) seems to me inappropriate for a "cookbook" -- namely, a reference from which people might well expect they can copy code or code patterns.
In particular, the "NC" clause is highly problematic, not least due to varied interpretations of what constitutes "commercial" activity in different jurisdictions around the world. It is my understanding, for example, that in Germany teaching in schools and universities would be considered a commercial activity. Perhaps it is your intention to limit the use of code examples from the cookbook in such contexts, but I would guess not! You can find all kinds of articles detailing real and potential problems with "NC" clauses around the web, but here's one good summary article.
The "SA" clause is also problematic. My reading of the "SA" clauses would imply that if I used code from the cookbook and modified it, I would be unable to release that code as part of an MIT/BSD licensed project, and I might be unable to release that code as part of any project that wasn't CC-SA licensed (although I'm not sure about this... perhaps a copyleft license would fulfil the requirement). Somewhat bizarrely, this would seem to imply that code from the cookbook couldn't be released as part of Pyramid itself, which is released under a BSD-like license.
It would be good to get some of this cleared up. If we need to hail someone who understands CC licenses (which is not something I can reasonably claim) to this issue I'd be happy to do so.
Given the references to Agendaless in CONTRIBUTORS.txt
I'm going to tag @mcdonc and @tseaver here.
The code samples in database/sqlalchemy.html don't close the session when the request is finished.
I was running into some problems with overflows in the SQLAlchemy connection pool, and modified the code to this:
def db(self):
def cleanup(self):
self.db.close()
self.add_finished_callback(cleanup)
return self.registry.settings['sessionmaker']()
Which so far seems to be working.
Hi,
Much of the FOSS community has moved from freenode.net to libera.chat. Pyramid should consider doing so also.
(See, e.g., the bottom of https://github.com/Pylons/pyramid_cookbook/blob/master/contributing.md
)
People continue to misinterpret the Pyramid Cookbook as "official" documentation, not community contributed. Renaming it to "Pyramid Community Cookbook" would be one step toward reducing that common misinterpretation. I do not suggest changing the URL or repo, just its name. (A new Sphinx theme would also help, but this is a quick fix.)
Please provide your opinion.
Is this recipe obsolete?
Basic Authentication Policy
http://docs.pylonsproject.org/projects/pyramid-cookbook/en/latest/auth/basic.html
paste was removed from Pyramid in v1.3:
http://docs.pylonsproject.org/projects/pyramid/en/latest/api/authentication.html#pyramid.authentication.BasicAuthAuthenticationPolicy
Also it looks like it was replaced in 1.4a3 by this:
http://docs.pylonsproject.org/projects/pyramid/en/latest/changes.html#id37
If a Pyramid historian can verify that finding, I'll remove the cookbook recipe.
In versions of Gunicorn prior to 20, use of egg:gunicorn#main
was
deprecated when used with external script runners and the Gunicorn
documentation suggested use of the Gunicorn CLI directly.
As requests came into the Gunicorn issue tracker for the ability to advanced
Paste features like specifying globals for interpolation in the config
file and using alternate server
blocks, it became clear that adding
these features would significantly inflate the surface of the Gunicorn
CLI. Furthermore, it was potentially confusing that using
the Gunicorn CLI while specifying another server in the server
block
would still use Gunicorn as the server.
For version 20, it was decided that it is best to let the tools of the
Paste ecosystem manage invoking the server. It is no longer deprecated
to specify egg:gunicorn#main
as the server and invoke Gunicorn with
pserve
. Gunicorn is fully supported as a Paste Deploy server factory.
Additionally, the Gunicorn CLI fully supports reading a Paste Deploy app
factory from a .ini
file. However, Gunicorn is not a Paste Script runner.
I suggest removing the "short story" from the gunicorn.rst. It is better to
suggest that users change their .ini
server block to use Gunicorn but to
keep the invocation of pserve
as before.
Here is what I get in "configuration/whirlwind_tour.rst":
The conflict was resolved because conflict the actions list got flushed
Maybe someone meant to say:
The conflict was resolved because the pending actions list got flushed
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.