Skip to content

Commit 64c9262

Browse files
authored
Merge pull request #59 from Deric-W/release3.1
Release3.1
2 parents 5f7c7c3 + 22c9777 commit 64c9262

File tree

6 files changed

+113
-23
lines changed

6 files changed

+113
-23
lines changed

.github/workflows/Tests.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ jobs:
66
Test:
77
strategy:
88
matrix:
9-
python-version: ["3.7", "3.8", "3.9", "3.10.0-alpha.4", "pypy-3.7"]
9+
python-version: ["3.7", "3.8", "3.9", "3.10", "pypy-3.7"]
1010
os: [ubuntu-latest, windows-latest]
1111

1212
runs-on: ${{ matrix.os }}

README.md

Lines changed: 91 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,12 @@ A script is called either by the configuration of the web server or a shebang an
1919
- unlike PHP, each code section of code must have a valid syntax of its own
2020
- if-Statements or loops can not span multiple code sections
2121

22+
### Runtime
23+
- module level constants are set and allow for source introspection if the backend supports it
24+
- `exit` and [`sys.exit`](https://docs.python.org/3/library/sys.html#sys.exit) terminate the script, not the whole server
25+
- [`atexit`](https://docs.python.org/3/library/atexit.html) registered functions dont get called until server shutdown in WSGI mode
26+
- since try statements can't span multiple code sections cleanup actions should be executed by [`register_shutdown_function`](#php-interface)
27+
2228
### Usage
2329
- can be used for
2430
- CLI scripts with the `pyhp-cli` command
@@ -38,34 +44,35 @@ A script is called either by the configuration of the web server or a shebang an
3844

3945
### PHP Interface
4046
- the following PHP features are available:
41-
- `$_SERVER` as `SERVER`
42-
- `$_REQUEST` as `REQUEST`
43-
- `$_GET` as `GET`
44-
- `$_POST` as `POST`
45-
- `$_COOKIE` as `COOKIE`
46-
- `$_FILES` as `FILES`
47-
- `http_response_code`
48-
- `header`
49-
- `headers_list`
50-
- `header_remove`
51-
- `headers_sent`
52-
- `header_register_callback` with an additional `replace` keyword argument to register multiple callbacks
53-
- `setcookie` with an additional `samesite` keyword argument
54-
- `setrawcookie` also with an additional `samesite` keyword argument
55-
- `opcache_compile_file` which raises Exceptions instead of returning `False` when compilation fails
56-
- `opcache_invalidate`
57-
- `opcache_is_script_cached`
58-
- `opcache_reset`
47+
- [`$_SERVER`](https://www.php.net/manual/en/reserved.variables.server.php) as `SERVER`
48+
- [`$_REQUEST`](https://www.php.net/manual/en/reserved.variables.request.php) as `REQUEST`
49+
- [`$_GET`](https://www.php.net/manual/en/reserved.variables.get.php) as `GET`
50+
- [`$_POST`](https://www.php.net/manual/en/reserved.variables.post.php) as `POST`
51+
- [`$_COOKIE`](https://www.php.net/manual/en/reserved.variables.cookies.php) as `COOKIE`
52+
- [`$_FILES`](https://www.php.net/manual/en/reserved.variables.files.php) as `FILES`
53+
- [`http_response_code`](https://www.php.net/manual/en/function.http-response-code)
54+
- [`header`](https://www.php.net/manual/en/function.header.php)
55+
- [`headers_list`](https://www.php.net/manual/en/function.headers-list.php)
56+
- [`header_remove`](https://www.php.net/manual/en/function.header-remove.php)
57+
- [`headers_sent`](https://www.php.net/manual/en/function.headers-sent.php)
58+
- [`header_register_callback`](https://www.php.net/manual/en/function.header-register-callback.php) with an additional `replace` keyword argument to register multiple callbacks
59+
- [`setcookie`](https://www.php.net/manual/en/function.setcookie.php) with an additional `samesite` keyword argument
60+
- [`setrawcookie`](https://www.php.net/manual/en/function.setrawcookie.php) also with an additional `samesite` keyword argument
61+
- [`register_shutdown_function`](https://www.php.net/manual/en/function.register-shutdown-function) with reversed callback execution order (LIFO)
62+
- [`opcache_compile_file`](https://www.php.net/manual/en/function.opcache-compile-file) which raises Exceptions instead of returning `False` when compilation fails
63+
- [`opcache_invalidate`](https://www.php.net/manual/en/function.opcache-invalidate.php)
64+
- [`opcache_is_script_cached`](https://www.php.net/manual/en/function.opcache-is-script-cached.php)
65+
- [`opcache_reset`](https://www.php.net/manual/en/function.opcache-reset.php)
5966

6067
### Config file
6168

62-
- is valid toml
69+
- is valid [toml](https://toml.io)
6370
- is looked for in these locations (no merging takes place, the first file wins):
6471
- the path given by the `-c` or `--config` cli argument
6572
- the path pointed to by the `PYHPCONFIG` environment variable
6673
- `~/.config/pyhp.toml`
6774
- `/etc/pyhp.toml`
68-
- raises a `RuntimeError` if not found
75+
- raises a [`RuntimeError`](https://docs.python.org/3/library/exceptions.html#RuntimeError) if not found
6976

7077
### Backends
7178

@@ -90,11 +97,74 @@ A script is called either by the configuration of the web server or a shebang an
9097
1. execute `debian/build_deb.sh` in the root directory of the project.
9198
2. Done! You can now install the debian package with `sudo dpkg -i python3-pyhp-core_{version}-1_all.deb`
9299

93-
- Optional: check if the recommended packages `python3-toml` and `python3-werkzeug` are installed to use the CLI commands
100+
- Optional: check if the recommended packages [`python3-toml`](https://packages.debian.org/search?keywords=python3-toml) and [`python3-werkzeug`](https://packages.debian.org/search?keywords=python3-werkzeug) are installed to use the CLI commands
94101
- Important: `pyhp-backend clear` will be executed on uninstall or upgrade if the backend is a cache, remember this when using paths containing `~` for the file cache
95102

96103
### Manually
97104
1. install the *pyhp-core* python package
98105
2. set the `PYHPCONFIG` environ variable or copy *pyhp.toml* to one of the config file locations
99106
3. Done! You can now use the `pyhp-*` commands
100107

108+
## WSGI Example
109+
110+
### Manually
111+
112+
```python
113+
import sys
114+
import re
115+
import tempfile
116+
from wsgiref.simple_server import make_server
117+
from pyhp.compiler import parsers, util, generic
118+
from pyhp.backends.files import Directory
119+
from pyhp.wsgi.apps import ConcurrentWSGIApp
120+
from pyhp.wsgi.proxys import LocalStackProxy
121+
from pyhp.wsgi.interfaces.php import PHPWSGIInterfaceFactory
122+
from pyhp.wsgi.interfaces.phputils import UploadStreamFactory
123+
124+
125+
compiler = util.Compiler(
126+
parsers.RegexParser(
127+
re.compile(r"<\?pyhp\s"),
128+
re.compile(r"\s\?>")
129+
),
130+
util.Dedenter(
131+
generic.GenericCodeBuilder(-1)
132+
)
133+
)
134+
135+
interface_factory = PHPWSGIInterfaceFactory(
136+
200,
137+
[("Content-type", "text/html; charset=\"UTF-8\"")],
138+
None,
139+
("GET", "POST", "COOKIE"),
140+
8000000,
141+
UploadStreamFactory(
142+
tempfile.gettempdir(),
143+
20
144+
)
145+
)
146+
147+
sys.stdout = proxy = LocalStackProxy(sys.stdout)
148+
149+
with Directory(".", compiler) as backend:
150+
with ConcurrentWSGIApp("tests/embedding/syntax.pyhp", backend, proxy, interface_factory) as app:
151+
with make_server("", 8000, app) as httpd:
152+
httpd.serve_forever()
153+
154+
```
155+
156+
### From a config file
157+
158+
```python
159+
from wsgiref.simple_server import make_server
160+
import toml
161+
from pyhp.wsgi.util import ConcurrentWSGIAppFactory
162+
163+
164+
config = toml.load("pyhp.toml")
165+
166+
with ConcurrentWSGIAppFactory.from_config(config) as factory:
167+
with factory.app("tests/embedding/syntax.pyhp") as app:
168+
with make_server("", 8000, app) as httpd:
169+
httpd.serve_forever()
170+
```

debian/changelog

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,21 @@
1+
python3-pyhp-core (3.1-1) stable; urgency=low
2+
3+
* eighth release
4+
* add pyhp-backend command
5+
* add backends.main submodule
6+
* add script to clear the cache on debian uninstall
7+
* add PHP opcache functions to PHPWSGIInterface
8+
* add TimestampedCodeSource methods to FileCacheSource and MemoryCacheSource
9+
* add support for python 3.10
10+
* move code from wsgi.utils to [Compiler|RegexParser].from_config
11+
* move load_config from main to seperate config submodule
12+
* move FileSource constructor logic to .from_path and .with_inferred_spec
13+
* fix CacheSourceContainer.gc and .clear not closing sources
14+
* fix warnings on debian uninstall
15+
* fix errors in ConcurrentWSGIApp.commit_removals if requesting a code source fails
16+
17+
-- Eric Wolf <[email protected]> Thu, 30 Sep 2021 18:59:00 +0100
18+
119
python3-pyhp-core (3.0-1) stable; urgency=low
220

321
* seventh release

pyhp/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313

1414
# package metadata
1515
# needs to be defined before .main is imported
16-
__version__ = "3.0"
16+
__version__ = "3.1"
1717
__author__ = "Eric Wolf"
1818
__maintainer__ = "Eric Wolf"
1919
__license__ = "GPLv3"

pyhp/wsgi/interfaces/php.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -355,6 +355,7 @@ def http_response_code(self, response_code: Optional[int] = None) -> int:
355355

356356
def register_shutdown_function(self, callback: Callable[..., None], *args: Any, **kwargs: Any) -> None:
357357
"""register a callback to be called on shutdown"""
358+
# execute in lifo order to prevent calling low level callbacks before high level ones
358359
self.shutdown_callbacks.appendleft((callback, args, kwargs))
359360

360361
def opcache_compile_file(self, filename: str) -> bool:

setup.cfg

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ classifiers =
1616
Programming Language :: Python :: 3.7
1717
Programming Language :: Python :: 3.8
1818
Programming Language :: Python :: 3.9
19+
Programming Language :: Python :: 3.10
1920
Operating System :: Microsoft :: Windows
2021
Operating System :: POSIX
2122
Intended Audience :: Developers

0 commit comments

Comments
 (0)