Skip to content

Commit

Permalink
Merge pull request #59 from Deric-W/release3.1
Browse files Browse the repository at this point in the history
Release3.1
  • Loading branch information
Deric-W authored Oct 5, 2021
2 parents 5f7c7c3 + 22c9777 commit 64c9262
Show file tree
Hide file tree
Showing 6 changed files with 113 additions and 23 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/Tests.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ jobs:
Test:
strategy:
matrix:
python-version: ["3.7", "3.8", "3.9", "3.10.0-alpha.4", "pypy-3.7"]
python-version: ["3.7", "3.8", "3.9", "3.10", "pypy-3.7"]
os: [ubuntu-latest, windows-latest]

runs-on: ${{ matrix.os }}
Expand Down
112 changes: 91 additions & 21 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,12 @@ A script is called either by the configuration of the web server or a shebang an
- unlike PHP, each code section of code must have a valid syntax of its own
- if-Statements or loops can not span multiple code sections

### Runtime
- module level constants are set and allow for source introspection if the backend supports it
- `exit` and [`sys.exit`](https://docs.python.org/3/library/sys.html#sys.exit) terminate the script, not the whole server
- [`atexit`](https://docs.python.org/3/library/atexit.html) registered functions dont get called until server shutdown in WSGI mode
- since try statements can't span multiple code sections cleanup actions should be executed by [`register_shutdown_function`](#php-interface)

### Usage
- can be used for
- CLI scripts with the `pyhp-cli` command
Expand All @@ -38,34 +44,35 @@ A script is called either by the configuration of the web server or a shebang an

### PHP Interface
- the following PHP features are available:
- `$_SERVER` as `SERVER`
- `$_REQUEST` as `REQUEST`
- `$_GET` as `GET`
- `$_POST` as `POST`
- `$_COOKIE` as `COOKIE`
- `$_FILES` as `FILES`
- `http_response_code`
- `header`
- `headers_list`
- `header_remove`
- `headers_sent`
- `header_register_callback` with an additional `replace` keyword argument to register multiple callbacks
- `setcookie` with an additional `samesite` keyword argument
- `setrawcookie` also with an additional `samesite` keyword argument
- `opcache_compile_file` which raises Exceptions instead of returning `False` when compilation fails
- `opcache_invalidate`
- `opcache_is_script_cached`
- `opcache_reset`
- [`$_SERVER`](https://www.php.net/manual/en/reserved.variables.server.php) as `SERVER`
- [`$_REQUEST`](https://www.php.net/manual/en/reserved.variables.request.php) as `REQUEST`
- [`$_GET`](https://www.php.net/manual/en/reserved.variables.get.php) as `GET`
- [`$_POST`](https://www.php.net/manual/en/reserved.variables.post.php) as `POST`
- [`$_COOKIE`](https://www.php.net/manual/en/reserved.variables.cookies.php) as `COOKIE`
- [`$_FILES`](https://www.php.net/manual/en/reserved.variables.files.php) as `FILES`
- [`http_response_code`](https://www.php.net/manual/en/function.http-response-code)
- [`header`](https://www.php.net/manual/en/function.header.php)
- [`headers_list`](https://www.php.net/manual/en/function.headers-list.php)
- [`header_remove`](https://www.php.net/manual/en/function.header-remove.php)
- [`headers_sent`](https://www.php.net/manual/en/function.headers-sent.php)
- [`header_register_callback`](https://www.php.net/manual/en/function.header-register-callback.php) with an additional `replace` keyword argument to register multiple callbacks
- [`setcookie`](https://www.php.net/manual/en/function.setcookie.php) with an additional `samesite` keyword argument
- [`setrawcookie`](https://www.php.net/manual/en/function.setrawcookie.php) also with an additional `samesite` keyword argument
- [`register_shutdown_function`](https://www.php.net/manual/en/function.register-shutdown-function) with reversed callback execution order (LIFO)
- [`opcache_compile_file`](https://www.php.net/manual/en/function.opcache-compile-file) which raises Exceptions instead of returning `False` when compilation fails
- [`opcache_invalidate`](https://www.php.net/manual/en/function.opcache-invalidate.php)
- [`opcache_is_script_cached`](https://www.php.net/manual/en/function.opcache-is-script-cached.php)
- [`opcache_reset`](https://www.php.net/manual/en/function.opcache-reset.php)

### Config file

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

### Backends

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

- Optional: check if the recommended packages `python3-toml` and `python3-werkzeug` are installed to use the CLI commands
- 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
- 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

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

## WSGI Example

### Manually

```python
import sys
import re
import tempfile
from wsgiref.simple_server import make_server
from pyhp.compiler import parsers, util, generic
from pyhp.backends.files import Directory
from pyhp.wsgi.apps import ConcurrentWSGIApp
from pyhp.wsgi.proxys import LocalStackProxy
from pyhp.wsgi.interfaces.php import PHPWSGIInterfaceFactory
from pyhp.wsgi.interfaces.phputils import UploadStreamFactory


compiler = util.Compiler(
parsers.RegexParser(
re.compile(r"<\?pyhp\s"),
re.compile(r"\s\?>")
),
util.Dedenter(
generic.GenericCodeBuilder(-1)
)
)

interface_factory = PHPWSGIInterfaceFactory(
200,
[("Content-type", "text/html; charset=\"UTF-8\"")],
None,
("GET", "POST", "COOKIE"),
8000000,
UploadStreamFactory(
tempfile.gettempdir(),
20
)
)

sys.stdout = proxy = LocalStackProxy(sys.stdout)

with Directory(".", compiler) as backend:
with ConcurrentWSGIApp("tests/embedding/syntax.pyhp", backend, proxy, interface_factory) as app:
with make_server("", 8000, app) as httpd:
httpd.serve_forever()

```

### From a config file

```python
from wsgiref.simple_server import make_server
import toml
from pyhp.wsgi.util import ConcurrentWSGIAppFactory


config = toml.load("pyhp.toml")

with ConcurrentWSGIAppFactory.from_config(config) as factory:
with factory.app("tests/embedding/syntax.pyhp") as app:
with make_server("", 8000, app) as httpd:
httpd.serve_forever()
```
18 changes: 18 additions & 0 deletions debian/changelog
Original file line number Diff line number Diff line change
@@ -1,3 +1,21 @@
python3-pyhp-core (3.1-1) stable; urgency=low

* eighth release
* add pyhp-backend command
* add backends.main submodule
* add script to clear the cache on debian uninstall
* add PHP opcache functions to PHPWSGIInterface
* add TimestampedCodeSource methods to FileCacheSource and MemoryCacheSource
* add support for python 3.10
* move code from wsgi.utils to [Compiler|RegexParser].from_config
* move load_config from main to seperate config submodule
* move FileSource constructor logic to .from_path and .with_inferred_spec
* fix CacheSourceContainer.gc and .clear not closing sources
* fix warnings on debian uninstall
* fix errors in ConcurrentWSGIApp.commit_removals if requesting a code source fails

-- Eric Wolf <robo-eric@gmx.de> Thu, 30 Sep 2021 18:59:00 +0100

python3-pyhp-core (3.0-1) stable; urgency=low

* seventh release
Expand Down
2 changes: 1 addition & 1 deletion pyhp/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@

# package metadata
# needs to be defined before .main is imported
__version__ = "3.0"
__version__ = "3.1"
__author__ = "Eric Wolf"
__maintainer__ = "Eric Wolf"
__license__ = "GPLv3"
Expand Down
1 change: 1 addition & 0 deletions pyhp/wsgi/interfaces/php.py
Original file line number Diff line number Diff line change
Expand Up @@ -355,6 +355,7 @@ def http_response_code(self, response_code: Optional[int] = None) -> int:

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

def opcache_compile_file(self, filename: str) -> bool:
Expand Down
1 change: 1 addition & 0 deletions setup.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ classifiers =
Programming Language :: Python :: 3.7
Programming Language :: Python :: 3.8
Programming Language :: Python :: 3.9
Programming Language :: Python :: 3.10
Operating System :: Microsoft :: Windows
Operating System :: POSIX
Intended Audience :: Developers
Expand Down

0 comments on commit 64c9262

Please sign in to comment.