Giter Site home page Giter Site logo

pyramid_cookbook's Introduction

Pyramid Community Cookbook

The Pyramid Community Cookbook presents topical, practical "recipes" of using Pyramid. It supplements the main Pyramid documentation.

To contribute your recipe to the Pyramid Community Cookbook, read Contributing.

pyramid_cookbook's People

Contributors

bbangert avatar blaflamme avatar caseman avatar cguardia avatar davidemoro avatar dnouri avatar ergo avatar goodwillcoding avatar jackdesert avatar jer-tx avatar keresian avatar kusut avatar mcdonc avatar mikeorr avatar mmerickel avatar nek4life avatar oneadvent avatar pauleveritt avatar reeedo avatar rmoorman avatar silenius avatar stevepiercy avatar themoo avatar tschm avatar tseaver avatar tshepang avatar twillis avatar virhilo avatar vog avatar wendall911 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

pyramid_cookbook's Issues

SQLAlchemy code samples don't close session

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.

Remove Basic Authentication Policy

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.

pylons-sphinx-themes is installed using the legacy 'setup.py install' method, this will fail with pip v23.1

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
...

Update Chameleon Internationalization to comply with Pyramid narrative docs

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'"

Asgi Websocket example not working on asgiref>=3.x

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.

grammar issue

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

Duplicate deployment sections

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!

Rename to "Pyramid Community Cookbook"

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.

Usage of wsgiapp2 over wsgiapp in porting/wsgi

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.

Question about file uploads

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!

Initial build of html docs fails with a 404

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

Need deployment instructions for Windows / IIS

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.

Licensing issues

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:

  1. 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.

  2. 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.

  3. 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.

Updates for Gunicorn 20

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.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.