Overview
========
plone.subrequest provides a mechanism for issuing subrequests under Zope.
Installation
============
Plone 4+
--------
This package is included by core Plone, so no special installation is required.
Zope
----
Load this package's ZCML in the usual manner.
Usage
=====
Basic usage
-----------
.. test-case: absolute
Call ``subrequest(url)``, it returns a response object.
>>> from plone.subrequest import subrequest
>>> response = subrequest('/folder1/@@url')
>>> response.getBody()
b'http://nohost/folder1'
.. test-case: response-write
``response.getBody()`` also works for code that calls ``response.write(data)``.
This one returns a text/non-byte value.
>>> response = subrequest('/@@response-write')
>>> response.getBody()
'Some data.\nSome more data.\n'
But in this case ``response.getBody()`` may only be called once.
>>> response.getBody()
Traceback (most recent call last):
...
ValueError: I/O operation on closed file
Accessing the response body as a file
-------------------------------------
.. test-case: stdout
Some code may call ``response.write(data)``.
>>> response = subrequest('/@@response-write')
In which case you may access response.stdout as file.
>>> response.stdout.seek(0, 0) or 0 # Py2 returns None, Py3 returns new position
0
>>> list(response.stdout)
['Some data.\n', 'Some more data.\n']
You can test whether a file was returned using ``response._wrote``.
>>> response._wrote
1
When you're done, close the file:
>>> response.stdout.close()
.. test-case: response-outputBody
Use ``response.outputBody()`` to ensure the body may be accessed as a file.
>>> from plone.subrequest import subrequest
>>> response = subrequest('/folder1/@@url')
>>> response._wrote
>>> response.outputBody()
>>> response._wrote
1
>>> response.stdout.seek(0, 0) or 0 # Py2 returns None, Py3 returns new position
0
>>> list(response.stdout)
['http://nohost/folder1']
Relative paths
--------------
.. test-case: relative
Relative paths are resolved relative to the parent request's location:
>>> from plone.subrequest.tests import traverse
>>> request = traverse('/folder1/@@test')
>>> response = subrequest('folder1A/@@url')
>>> response.getBody()
b'http://nohost/folder1/folder1A'
.. test-case: relative-default-view
This takes account of default view's url.
>>> request = traverse('/folder1')
>>> request['URL'] == 'http://nohost/folder1/@@test'
True
>>> response = subrequest('folder1A/@@url')
>>> response.getBody()
b'http://nohost/folder1/folder1A'
Virtual hosting
---------------
.. test-case: virtual-hosting
When virtual hosting is used, absolute paths are traversed from the virtual host root.
>>> request = traverse('/VirtualHostBase/http/nohost:80/folder1/VirtualHostRoot/')
>>> response = subrequest('/folder1A/@@url')
>>> response.getBody()
b'http://nohost/folder1A'
Specifying the root
-------------------
.. test-case: specify-root
You may also set the root object explicitly
>>> app = layer['app']
>>> response = subrequest('/folder1A/@@url', root=app.folder1)
>>> response.getBody()
b'http://nohost/folder1/folder1A'
Error responses
---------------
.. test-case: not-found
Subrequests may not be found.
>>> response = subrequest('/not-found')
>>> response.status
404
.. test-case: error-response
Or might raise an error.
>>> response = subrequest('/@@error')
>>> response.status
500
Or might raise an error rendered by a custom error view.
>>> response = subrequest('/@@custom-error')
>>> response.status
500
>>> response.body
b'Custom exception occurred: A custom error'
.. test-case: status-ok
So check for the expected status.
>>> response = subrequest('/')
>>> response.status == 200
True
Handling subrequests
--------------------
The parent request is set as PARENT_REQUEST onto subrequests.
Subrequests also provide the ``plone.subrequest.interfaces.ISubRequest``
marker interface.
Changelog
=========
.. You should *NOT* be adding new change log entries to this file.
You should create a file in the news directory instead.
For helpful instructions, please see:
https://github.com/plone/plone.releaser/blob/master/ADD-A-NEWS-ITEM.rst
.. towncrier release notes start
2.0.4 (2023-06-09)
------------------
Internal:
- Update configuration files.
[plone devs] (b5084eff)
2.0.3 (2023-03-14)
------------------
Internal:
- Update configuration files.
[plone devs] (13d8d6c0)
2.0.2 (2023-02-07)
------------------
Bug fixes:
- Declare dependencies as found by z3c.dependencychecker.
[gforcada] (#1)
2.0.1 (2023-01-27)
------------------
Internal:
- Unify repository configuration via github.com/plone/meta.
[gforcada, maurits] (#1)
2.0.0 (2022-11-30)
------------------
Bug fixes:
- Final release.
[gforcada] (#600)
2.0.0b1 (2022-09-07)
--------------------
Breaking changes:
- Drop Python 2 support and update code style.
[jensens] (#25)
1.9.3 (2020-09-26)
------------------
Bug fixes:
- Fixed deprecation warning for zope.site.hooks.
[maurits] (#24)
1.9.2 (2020-04-22)
------------------
Bug fixes:
- Minor packaging updates. (#1)
1.9.1 (2019-04-29)
------------------
Bug fixes:
- fix regression bug which was breaking in Python 2.7 when tiles contain non-ascii characters [MrTango] (#22)
1.9.0 (2018-12-11)
------------------
Breaking changes:
- Remove five.globalrequest dependency.
It has been deprecated upstream (on Zope 4).
[gforcada]
1.8.6 (2018-09-23)
------------------
New features:
- Fix importsi without ZServer
[pbauer]
Bug fixes:
- More Python 3 compatibility.
[ale-rt, thet]
- Make test dependency on Archetypes optional.
[davisagli]
1.8.5 (2018-01-30)
------------------
Bug fixes:
- Add Python 2 / 3 compatibility
[pbauer]
1.8.4 (2017-09-06)
------------------
New features:
- Add support for Zope exception views when explicit exception handler
is not defined
[datakurre]
Bug fixes:
- Fix issue where the example unauthorized_exception_handler did
not properly set response status code
[datakurre]
1.8.3 (2017-08-30)
------------------
Bug fixes:
- Reverted "Remove vurl-parts from path", which resulted in broken p.a.mosaic pages
[thet]
1.8.2 (2017-07-20)
------------------
Bug fixes:
- Remove vurl-parts from path
[awello]
1.8.1 (2017-06-28)
------------------
Bug fixes:
- Remove unittest2 dependency
[kakshay21]
1.8 (2016-11-01)
----------------
New features:
- Provide an exception-handler for rewriting Unauthorized to 401's.
[jensens]
1.7.0 (2016-05-04)
------------------
New:
- Allow to pass a custom exception handler for the response.
[jensens]
Fixes:
- When a subrequest modified the DB (or prior to the subrequest the main request),
the oids annotated to the requests were doubled with each subsequent subrequest.
This resulted in out-of-memory errors when using lots of subrequests,
such as it happens on Mosaic based sites with a certain amount of tiles.
Fixed by only adding new oids, not already known by parent request.
[jensens]
- Housekeeping: isort imports, autopep8, minor manual cleanup (no zope.app. imports).
[jensens]
1.6.11 (2015-09-07)
-------------------
- propagate IDisableCSRFProtection interface on subrequest to parent request object
[vangheem]
1.6.10 (2015-08-14)
-------------------
- propagate registered safe writes from plone.protect to parent request object.
[vangheem]
1.6.9 (2015-03-21)
------------------
- Workaround for broken test because of missing dependency declaration in
upstream package, see https://github.com/plone/plone.app.blob/issues/19
for details.
[jensens]
- Housekeeping and code cleanup (pep8, et al).
[jensens]
- Fix issue where new cookies from the main request.response are not passed to
subrequests.
[datakurre]
- normalise request path_info so that string indexing works properly.
[gweiss]
1.6.8 (2014-03-04)
------------------
- Handle sub-requests which contain a doubled // in the path.
[gweis]
1.6.7 (2012-10-22)
------------------
- Ensure correct handling of bare virtual hosting urls.
[elro]
1.6.6 (2012-06-29)
------------------
- Log errors that occur handling a subrequest to help debug plone.app.theming
errors including content from a different url
[anthonygerrard]
1.6.5 (2012-04-15)
------------------
- Ensure parent url is a string and not unicode.
[davisagli]
1.6.4 - 2012-03-22
------------------
- Fix problems with double encoding some unicode charse by not copying too
many ``other`` variables.
[elro]
1.6.3 - 2012-02-12
------------------
- Copy ``other`` request variables such as ``LANGUAGE`` to subrequest.
[elro]
1.6.2 - 2011-07-04
------------------
- Handle spaces in default documents. http://dev.plone.org/plone/ticket/12278
1.6.1 - 2011-07-04
------------------
- Move tests to package directory to making testing possible when installed
normally.
1.6 - 2011-06-06
----------------
- Ensure url is a string and not unicode.
[elro]
1.6b2 - 2011-05-20
------------------
- Set PARENT_REQUEST and add ISubRequest interface to subrequests.
[elro]
1.6b1 - 2011-02-11
------------------
- Handle IStreamIterator.
[elro]
- Simplify API so ``response.getBody()`` always works.
[elro]
1.5 - 2010-11-26
----------------
- Merge cookies from subrequest response into parent response.
[awello]
1.4 - 2010-11-10
----------------
- First processInput, then traverse (fixes #11254)
[awello]
1.3 - 2010-08-24
----------------
- Fixed bug with virtual hosting and quoted paths.
[elro]
1.2 - 2010-08-16
----------------
- Restore zope.component site after subrequest.
[elro]
1.1 - 2010-08-14
----------------
- Virtual hosting, relative url and error response support.
[elro]
1.0 - 2010-07-28
----------------
- Initial release.
[elro]
Raw data
{
"_id": null,
"home_page": "https://github.com/plone/plone.subrequest",
"name": "plone.subrequest",
"maintainer": "",
"docs_url": null,
"requires_python": ">=3.8",
"maintainer_email": "",
"keywords": "plone",
"author": "Plone Foundation",
"author_email": "plone-developers@lists.sourceforge.net",
"download_url": "https://files.pythonhosted.org/packages/0f/91/0a64786920d4aa466c7001d88753c3550ee2019b938c9bb47cf36824ba55/plone.subrequest-2.0.4.tar.gz",
"platform": "Any",
"description": "\nOverview\n========\n\nplone.subrequest provides a mechanism for issuing subrequests under Zope.\n\nInstallation\n============\n\nPlone 4+\n--------\n\nThis package is included by core Plone, so no special installation is required.\n\n\nZope\n----\n\nLoad this package's ZCML in the usual manner.\n\n\n\n\nUsage\n=====\n\nBasic usage\n-----------\n\n.. test-case: absolute\n\nCall ``subrequest(url)``, it returns a response object.\n\n >>> from plone.subrequest import subrequest\n >>> response = subrequest('/folder1/@@url')\n >>> response.getBody()\n b'http://nohost/folder1'\n\n.. test-case: response-write\n\n``response.getBody()`` also works for code that calls ``response.write(data)``.\nThis one returns a text/non-byte value.\n\n >>> response = subrequest('/@@response-write')\n >>> response.getBody()\n 'Some data.\\nSome more data.\\n'\n\nBut in this case ``response.getBody()`` may only be called once.\n\n >>> response.getBody()\n Traceback (most recent call last):\n ...\n ValueError: I/O operation on closed file\n\nAccessing the response body as a file\n-------------------------------------\n\n.. test-case: stdout\n\nSome code may call ``response.write(data)``.\n\n >>> response = subrequest('/@@response-write')\n\nIn which case you may access response.stdout as file.\n\n >>> response.stdout.seek(0, 0) or 0 # Py2 returns None, Py3 returns new position\n 0\n >>> list(response.stdout)\n ['Some data.\\n', 'Some more data.\\n']\n\nYou can test whether a file was returned using ``response._wrote``.\n\n >>> response._wrote\n 1\n\nWhen you're done, close the file:\n\n >>> response.stdout.close()\n\n.. test-case: response-outputBody\n\nUse ``response.outputBody()`` to ensure the body may be accessed as a file.\n\n >>> from plone.subrequest import subrequest\n >>> response = subrequest('/folder1/@@url')\n >>> response._wrote\n >>> response.outputBody()\n >>> response._wrote\n 1\n >>> response.stdout.seek(0, 0) or 0 # Py2 returns None, Py3 returns new position\n 0\n >>> list(response.stdout)\n ['http://nohost/folder1']\n\nRelative paths\n--------------\n\n.. test-case: relative\n\nRelative paths are resolved relative to the parent request's location:\n\n >>> from plone.subrequest.tests import traverse\n >>> request = traverse('/folder1/@@test')\n >>> response = subrequest('folder1A/@@url')\n >>> response.getBody()\n b'http://nohost/folder1/folder1A'\n\n.. test-case: relative-default-view\n\nThis takes account of default view's url.\n\n >>> request = traverse('/folder1')\n >>> request['URL'] == 'http://nohost/folder1/@@test'\n True\n >>> response = subrequest('folder1A/@@url')\n >>> response.getBody()\n b'http://nohost/folder1/folder1A'\n\nVirtual hosting\n---------------\n\n.. test-case: virtual-hosting\n\nWhen virtual hosting is used, absolute paths are traversed from the virtual host root.\n\n >>> request = traverse('/VirtualHostBase/http/nohost:80/folder1/VirtualHostRoot/')\n >>> response = subrequest('/folder1A/@@url')\n >>> response.getBody()\n b'http://nohost/folder1A'\n\nSpecifying the root\n-------------------\n\n.. test-case: specify-root\n\nYou may also set the root object explicitly\n\n >>> app = layer['app']\n >>> response = subrequest('/folder1A/@@url', root=app.folder1)\n >>> response.getBody()\n b'http://nohost/folder1/folder1A'\n\nError responses\n---------------\n\n.. test-case: not-found\n\nSubrequests may not be found.\n\n >>> response = subrequest('/not-found')\n >>> response.status\n 404\n\n.. test-case: error-response\n\nOr might raise an error.\n\n >>> response = subrequest('/@@error')\n >>> response.status\n 500\n\nOr might raise an error rendered by a custom error view.\n\n >>> response = subrequest('/@@custom-error')\n >>> response.status\n 500\n >>> response.body\n b'Custom exception occurred: A custom error'\n\n.. test-case: status-ok\n\nSo check for the expected status.\n\n >>> response = subrequest('/')\n >>> response.status == 200\n True\n\nHandling subrequests\n--------------------\n\nThe parent request is set as PARENT_REQUEST onto subrequests.\n\nSubrequests also provide the ``plone.subrequest.interfaces.ISubRequest``\nmarker interface.\n\n\n\n\nChangelog\n=========\n\n.. You should *NOT* be adding new change log entries to this file.\n You should create a file in the news directory instead.\n For helpful instructions, please see:\n https://github.com/plone/plone.releaser/blob/master/ADD-A-NEWS-ITEM.rst\n\n.. towncrier release notes start\n\n2.0.4 (2023-06-09)\n------------------\n\nInternal:\n\n\n- Update configuration files.\n [plone devs] (b5084eff)\n\n\n2.0.3 (2023-03-14)\n------------------\n\nInternal:\n\n\n- Update configuration files.\n [plone devs] (13d8d6c0)\n\n\n2.0.2 (2023-02-07)\n------------------\n\nBug fixes:\n\n\n- Declare dependencies as found by z3c.dependencychecker.\n [gforcada] (#1)\n\n\n2.0.1 (2023-01-27)\n------------------\n\nInternal:\n\n\n- Unify repository configuration via github.com/plone/meta.\n [gforcada, maurits] (#1)\n\n\n2.0.0 (2022-11-30)\n------------------\n\nBug fixes:\n\n\n- Final release.\n [gforcada] (#600)\n\n\n2.0.0b1 (2022-09-07)\n--------------------\n\nBreaking changes:\n\n\n- Drop Python 2 support and update code style.\n [jensens] (#25)\n\n\n1.9.3 (2020-09-26)\n------------------\n\nBug fixes:\n\n\n- Fixed deprecation warning for zope.site.hooks.\n [maurits] (#24)\n\n\n1.9.2 (2020-04-22)\n------------------\n\nBug fixes:\n\n\n- Minor packaging updates. (#1)\n\n\n1.9.1 (2019-04-29)\n------------------\n\nBug fixes:\n\n\n- fix regression bug which was breaking in Python 2.7 when tiles contain non-ascii characters [MrTango] (#22)\n\n\n1.9.0 (2018-12-11)\n------------------\n\nBreaking changes:\n\n- Remove five.globalrequest dependency.\n It has been deprecated upstream (on Zope 4).\n [gforcada]\n\n\n1.8.6 (2018-09-23)\n------------------\n\nNew features:\n\n- Fix importsi without ZServer\n [pbauer]\n\nBug fixes:\n\n- More Python 3 compatibility.\n [ale-rt, thet]\n\n- Make test dependency on Archetypes optional.\n [davisagli]\n\n\n1.8.5 (2018-01-30)\n------------------\n\nBug fixes:\n\n- Add Python 2 / 3 compatibility\n [pbauer]\n\n\n1.8.4 (2017-09-06)\n------------------\n\nNew features:\n\n- Add support for Zope exception views when explicit exception handler\n is not defined\n [datakurre]\n\nBug fixes:\n\n- Fix issue where the example unauthorized_exception_handler did\n not properly set response status code\n [datakurre]\n\n\n1.8.3 (2017-08-30)\n------------------\n\nBug fixes:\n\n- Reverted \"Remove vurl-parts from path\", which resulted in broken p.a.mosaic pages\n [thet]\n\n\n1.8.2 (2017-07-20)\n------------------\n\nBug fixes:\n\n- Remove vurl-parts from path\n [awello]\n\n\n1.8.1 (2017-06-28)\n------------------\n\nBug fixes:\n\n- Remove unittest2 dependency\n [kakshay21]\n\n\n1.8 (2016-11-01)\n----------------\n\nNew features:\n\n- Provide an exception-handler for rewriting Unauthorized to 401's.\n [jensens]\n\n\n1.7.0 (2016-05-04)\n------------------\n\nNew:\n\n- Allow to pass a custom exception handler for the response.\n [jensens]\n\nFixes:\n\n- When a subrequest modified the DB (or prior to the subrequest the main request),\n the oids annotated to the requests were doubled with each subsequent subrequest.\n This resulted in out-of-memory errors when using lots of subrequests,\n such as it happens on Mosaic based sites with a certain amount of tiles.\n Fixed by only adding new oids, not already known by parent request.\n [jensens]\n\n- Housekeeping: isort imports, autopep8, minor manual cleanup (no zope.app. imports).\n [jensens]\n\n\n1.6.11 (2015-09-07)\n-------------------\n\n- propagate IDisableCSRFProtection interface on subrequest to parent request object\n [vangheem]\n\n\n1.6.10 (2015-08-14)\n-------------------\n\n- propagate registered safe writes from plone.protect to parent request object.\n [vangheem]\n\n\n1.6.9 (2015-03-21)\n------------------\n\n- Workaround for broken test because of missing dependency declaration in\n upstream package, see https://github.com/plone/plone.app.blob/issues/19\n for details.\n [jensens]\n\n- Housekeeping and code cleanup (pep8, et al).\n [jensens]\n\n- Fix issue where new cookies from the main request.response are not passed to\n subrequests.\n [datakurre]\n\n- normalise request path_info so that string indexing works properly.\n [gweiss]\n\n\n1.6.8 (2014-03-04)\n------------------\n- Handle sub-requests which contain a doubled // in the path.\n [gweis]\n\n1.6.7 (2012-10-22)\n------------------\n\n- Ensure correct handling of bare virtual hosting urls.\n [elro]\n\n1.6.6 (2012-06-29)\n------------------\n\n- Log errors that occur handling a subrequest to help debug plone.app.theming\n errors including content from a different url\n [anthonygerrard]\n\n1.6.5 (2012-04-15)\n------------------\n\n- Ensure parent url is a string and not unicode.\n [davisagli]\n\n1.6.4 - 2012-03-22\n------------------\n\n- Fix problems with double encoding some unicode charse by not copying too\n many ``other`` variables.\n [elro]\n\n1.6.3 - 2012-02-12\n------------------\n\n- Copy ``other`` request variables such as ``LANGUAGE`` to subrequest.\n [elro]\n\n1.6.2 - 2011-07-04\n------------------\n\n- Handle spaces in default documents. http://dev.plone.org/plone/ticket/12278\n\n1.6.1 - 2011-07-04\n------------------\n\n- Move tests to package directory to making testing possible when installed\n normally.\n\n1.6 - 2011-06-06\n----------------\n\n- Ensure url is a string and not unicode.\n [elro]\n\n1.6b2 - 2011-05-20\n------------------\n\n- Set PARENT_REQUEST and add ISubRequest interface to subrequests.\n [elro]\n\n1.6b1 - 2011-02-11\n------------------\n\n- Handle IStreamIterator.\n [elro]\n\n- Simplify API so ``response.getBody()`` always works.\n [elro]\n\n1.5 - 2010-11-26\n----------------\n\n- Merge cookies from subrequest response into parent response.\n [awello]\n\n1.4 - 2010-11-10\n----------------\n\n- First processInput, then traverse (fixes #11254)\n [awello]\n\n1.3 - 2010-08-24\n----------------\n\n- Fixed bug with virtual hosting and quoted paths.\n [elro]\n\n1.2 - 2010-08-16\n----------------\n\n- Restore zope.component site after subrequest.\n [elro]\n\n1.1 - 2010-08-14\n----------------\n\n- Virtual hosting, relative url and error response support.\n [elro]\n\n1.0 - 2010-07-28\n----------------\n\n- Initial release.\n [elro]\n\n",
"bugtrack_url": null,
"license": "GPL version 2",
"summary": "Subrequests for Zope2",
"version": "2.0.4",
"project_urls": {
"Homepage": "https://github.com/plone/plone.subrequest"
},
"split_keywords": [
"plone"
],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "3fac22b657e3af944b62bd04b856cbdfe792093a213988e8af7d05ee44877f8f",
"md5": "fee381491ac7bcb9c37a867f048a4a8c",
"sha256": "1352580d78ae7e4438c62bd49a80dbd1fb9eb5078b6f340c99791f84a31f8442"
},
"downloads": -1,
"filename": "plone.subrequest-2.0.4-py3-none-any.whl",
"has_sig": false,
"md5_digest": "fee381491ac7bcb9c37a867f048a4a8c",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.8",
"size": 14612,
"upload_time": "2023-06-09T20:15:35",
"upload_time_iso_8601": "2023-06-09T20:15:35.450864Z",
"url": "https://files.pythonhosted.org/packages/3f/ac/22b657e3af944b62bd04b856cbdfe792093a213988e8af7d05ee44877f8f/plone.subrequest-2.0.4-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "0f910a64786920d4aa466c7001d88753c3550ee2019b938c9bb47cf36824ba55",
"md5": "90417701028623696428f332112bfe28",
"sha256": "565f97138027542379917828ad71375371b20af9853288f8e9c49cb3dfb367ea"
},
"downloads": -1,
"filename": "plone.subrequest-2.0.4.tar.gz",
"has_sig": false,
"md5_digest": "90417701028623696428f332112bfe28",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.8",
"size": 25816,
"upload_time": "2023-06-09T20:15:37",
"upload_time_iso_8601": "2023-06-09T20:15:37.585498Z",
"url": "https://files.pythonhosted.org/packages/0f/91/0a64786920d4aa466c7001d88753c3550ee2019b938c9bb47cf36824ba55/plone.subrequest-2.0.4.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2023-06-09 20:15:37",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "plone",
"github_project": "plone.subrequest",
"travis_ci": false,
"coveralls": false,
"github_actions": true,
"tox": true,
"lcname": "plone.subrequest"
}