{"id":29433771,"url":"https://github.com/jenner/pyramid_extdirect","last_synced_at":"2025-07-26T08:37:13.813Z","repository":{"id":62582931,"uuid":"837818","full_name":"jenner/pyramid_extdirect","owner":"jenner","description":"Sencha ExtDirect Router for the Pyramid web application development framework","archived":false,"fork":false,"pushed_at":"2021-03-09T14:15:20.000Z","size":81,"stargazers_count":10,"open_issues_count":0,"forks_count":3,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-06-25T21:55:09.541Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/jenner.png","metadata":{"files":{"readme":"README.rst","changelog":"CHANGES.txt","contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2010-08-14T16:21:30.000Z","updated_at":"2021-03-09T14:15:22.000Z","dependencies_parsed_at":"2022-11-03T22:01:51.066Z","dependency_job_id":null,"html_url":"https://github.com/jenner/pyramid_extdirect","commit_stats":null,"previous_names":[],"tags_count":10,"template":false,"template_full_name":null,"purl":"pkg:github/jenner/pyramid_extdirect","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jenner%2Fpyramid_extdirect","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jenner%2Fpyramid_extdirect/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jenner%2Fpyramid_extdirect/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jenner%2Fpyramid_extdirect/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jenner","download_url":"https://codeload.github.com/jenner/pyramid_extdirect/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jenner%2Fpyramid_extdirect/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":265080006,"owners_count":23708098,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2025-07-13T01:30:23.188Z","updated_at":"2025-07-13T01:30:23.894Z","avatar_url":"https://github.com/jenner.png","language":"Python","funding_links":[],"categories":["Other"],"sub_categories":[],"readme":"pyramid_extdirect README\n===========================\n\nIntroduction:\n-------------\n\nThis `pyramid`_ plugin provides a router for the `ExtDirect Sencha`_ API\nincluded in `ExtJS`_ .\n\n.. _`pyramid`: http://docs.pylonsproject.org/en/latest/docs/pyramid.html\n.. _`ExtDirect Sencha`: https://docs.sencha.com/extjs/6.0/backend_connectors/direct/specification.html\n.. _`ExtJS`: http://www.sencha.com/products/extjs/\n\n\nExtDirect allows to run server-side callbacks directly through JavaScript without\nthe extra AJAX boilerplate. The typical ExtDirect usage scenario goes like this::\n\n    MyApp.SomeClass.fooMethod(foo, bar, function(response) {\n        // do cool things with response\n    });\n\nor even better, if ExtDirect is used in a GridStore::\n\n    var usersStore = new Ext.data.Store({\n        fields: ['id', 'name', 'title'],\n        proxy: {\n            type: 'direct',\n            directFn: MyApp.Users.loadAll,\n            reader: {\n                type: 'json',\n                rootProperty: 'items'\n            }\n        }\n        // ...\n    });\n\nHere ``MyApp`` is the application namespace, ``SomeClass`` or\n``Grids`` are classes or *actions* and ``fooMethod`` and \n``loadGridData`` are methods.\n\nUsage example:\n--------------\n\nThe minimum requirement for pyramid_extdirect is to create an ExtDirect API and Router::\n\n    from pyramid.config import Configurator\n    from exampleapp.resources import Root\n\n    def main(global_config, **settings):\n        \"\"\" This function returns a Pyramid WSGI application.\n        \"\"\"\n        config = Configurator(root_factory=Root, settings=settings)\n        config.add_view('exampleapp.views.my_view',\n                        context='exampleapp:resources.Root',\n                        renderer='exampleapp:templates/mytemplate.pt')\n        config.add_static_view('static', 'exampleapp:static')\n        # let pyramid_extdirect create all the needed views automatically\n        config.include('pyramid_extdirect')\n        # scan your code once to make sure the @extdirect_method decorators\n        # are picked up\n        config.scan()\n        return config.make_wsgi_app()\n\nAfter this you can decorate arbitrary functions or class methods using @extdirect_method::\n\n    @extdirect_method(action='SomeAction')\n    def do_stuff(a, b, c):\n        return a + b + c\n\nOr, if you'd like to group your methods into classes (actions), you can do so by decoration\nclass methods:\n\nThe ``UsersController`` class could combine all methods for users CRUD operations, the only\nrequirement is that this class accepts ``request`` as its first and only constructor argument,\nthis is needed to make sure your methods have access to ``request`` at any time::\n\n    from pyramid_extdirect import extdirect_method\n\n    class UsersController(object):\n\n        __extdirect_settings__ = { \n            'default_action_name': 'Users',\n            'default_permission': 'view'\n        }\n\n        def __init__(self, request):\n            self.request = request\n\n        # we don't need to set ``action`` here, because\n        # it's already defined via __extdirect_settings__\n        @extdirect_method(permission='view', method_name='loadAll')\n        def load_all(self, params):\n            # params is a simple dict that will contain the\n            # paging and sorting options as well as any other\n            # extra parameters (defined using proxy.extraParams\n            # your store config)\n            users = []\n            for user in users_db.fetch_all():\n                users.append({\n                    id: obj.id,\n                    name: obj.name,\n                    title: obj.title,\n                    # ...\n                })\n            return dict(success=True, items=users)\n\nAs you can see, the ``Users#loadAll`` method doesn't even know it's been called through\na HTTP request, it's just a plain old python method which returns a dict.\nThe ``@extdirect_method(permission='view')`` decoration adds it to\nthe ``Users`` action (also making sure only users with *view* permission are allowed\nto run it). We're returning a ``dict`` here simply because the AJAX response sent to\nthe client has to be JSON serializable. By default python JSON marshallers can only\nencode/decode builtin python primitives. ``pyramid_extdirect`` has a small helper\nthough, that checks if an object has a method called ``json_repr()`` (which should\nreturn a JSON serializable dict/list/string/number/etc.) and if found, this method is\nused to decode an instance to its JSONable version.\nYou can define a ``__extdirect_settings__`` property in a class to define a default\n``action`` and ``permission``, so in the example above we could also just use ``@extdirect_method()``.\n\nSometimes you need to use the upload features of ExtDirect. Since uploads cannot\nbe done using AJAX (through JSON-encoded request body) Ext does a little trick\nby creating a hidden iframe and posting a form within this iframe to the server.\nHowever, ExtDirect needs to know in advance, that your code might receive uploads.\nIn ``pyramid_extdirect`` decorators this is done by adding a ``accepts_files``\nparameter to the ``@extdirect_method`` decorator::\n\n    class Users(object):\n        ...\n        @extdirect_method(accepts_files=True)\n        def upload_avatar(self, uploaded_file):\n            # uploaded_file is now a FieldStorage instance\n\nIn some situations it is absolutely necessary to access the ``request`` object\nin your functions and you don't want to create an extra class (where the request would be\npassed in to the class constructor) -- this can be achieved by passing ``request_as_last_param`` to the\ndecorator::\n\n    from pyramid.security import authenticated_userid\n\n    @extdirect_method(action='App', request_as_last_param=True):\n    def get_current_user(request):\n        return authenticated_userid(request)\n\n-- \nIgor Stroh, \u003cigor.stroh -at- rulim.de\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjenner%2Fpyramid_extdirect","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjenner%2Fpyramid_extdirect","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjenner%2Fpyramid_extdirect/lists"}