Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix windows build #5

Open
wants to merge 31 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
31853e9
Fix windows build
Feb 10, 2020
ad9f311
Add support for callbacks
zeevro Feb 11, 2020
104e445
Add .gitignore
zeevro Feb 11, 2020
f1fabd7
Add example code
zeevro Feb 11, 2020
94ba876
Revamp setup.py
zeevro Feb 11, 2020
69be6a0
Examples
Feb 11, 2020
34bdc2e
Revamp setup.py; add classifiers.
Feb 11, 2020
29901d7
VS Code workspace, test.py
Feb 12, 2020
6af0518
Better project management
Feb 12, 2020
b2dda48
Remove silly print from test.py
Feb 12, 2020
a0dddd2
Added self to WebView.callback
Feb 12, 2020
30eab34
Better docstrings on WebView members
Feb 12, 2020
9891e9f
Better testing
Feb 12, 2020
7a8cab7
Module description for webview
zeevro Feb 12, 2020
e371d41
Restore mistakenly deleted MANIFEST.in
zeevro Feb 15, 2020
cd686be
Tests stuff
zeevro Feb 15, 2020
ca8d65b
Better docs
zeevro Feb 15, 2020
636c964
Added build action
zeevro Feb 16, 2020
f13b3cb
Change .yaml -> .yml
zeevro Feb 16, 2020
fc0c974
build.yml
zeevro Feb 16, 2020
e839e76
Create build2.yml
zeevro Feb 16, 2020
5881905
Update build.yml
zeevro Feb 17, 2020
4c63455
Delete build2.yml
zeevro Feb 17, 2020
5a9e966
Add pywebview
zeevro Mar 5, 2020
2121736
Remove webview/
zeevro Jan 28, 2021
1acf980
Add webview/ as a module
zeevro Jan 28, 2021
b29b97d
WIP: It's working!! (including rudimentary binding)
zeevro Jan 28, 2021
0ad4c7b
Binding support
zeevro Apr 14, 2021
893dd7d
Add TODO to README.md
zeevro Apr 14, 2021
78be52f
Disable freeing the GIL in WebView.run() as it crashes examples/minim…
zeevro Apr 14, 2021
9f41630
Better JS in examples/minimal.py
zeevro Apr 14, 2021
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
.vscode/settings.json
build/
dist/
__pycache__
*.pyc
*.egg-info
*.dist-info
*.pyd
*.so
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[submodule "webview"]
path = webview
url = https://github.com/webview/webview
19 changes: 19 additions & 0 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "WebView: Test",
"type": "python",
"request": "launch",
"program": "${workspaceFolder}/test.py",
"args": [
"${file}"
],
"console": "integratedTerminal",
"justMyCode": true
}
]
}
16 changes: 16 additions & 0 deletions .vscode/make_settings_json.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#!/usr/bin/python3
import os
import platform
import string
import sys
import sysconfig

webview_platform = {'Linux': 'GTK', 'Darwin': 'COCOA', 'Windows': 'WINAPI'}.get(platform.system(), 'GTK')
python_include_dir = sysconfig.get_path('include').replace('\\', '\\\\')
py_major_version = sys.version_info[0]

with open('settings.json.template') as f:
settings = string.Template(f.read()).safe_substitute(locals())

with open('settings.json', 'w') as f:
f.write(settings)
9 changes: 9 additions & 0 deletions .vscode/settings.json.template
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"C_Cpp.default.defines": [
"PY_MAJOR_VERSION=${py_major_version}",
"WEBVIEW_${webview_platform}"
],
"C_Cpp.default.includePath": [
"${python_include_dir}"
]
}
61 changes: 61 additions & 0 deletions .vscode/tasks.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
{
// See https://go.microsoft.com/fwlink/?LinkId=733558
// for the documentation about the tasks.json format
"version": "2.0.0",
"tasks": [
{
"label": "Build",
"type": "shell",
"options": {
"cwd": "${workspaceFolder}"
},
"command": "${config:python.pythonPath} setup.py build_ext -f --inplace",
"group": {
"kind": "build",
"isDefault": true
},
"problemMatcher": [
"$msCompile",
"$gcc"
]
},
{
"label": "Build distributables",
"type": "shell",
"options": {
"cwd": "${workspaceFolder}"
},
"command": "${config:python.pythonPath} setup.py sdist bdist_wheel",
"group": "build",
"problemMatcher": []
},
{
"label": "Test",
"type": "shell",
"options": {
"cwd": "${workspaceFolder}"
},
"command": "${config:python.pythonPath} test.py",
"group": {
"kind": "test",
"isDefault": true
},
"problemMatcher": []
},
{
"label": "Create settings.json",
"type": "shell",
"command": "${config:python.pythonPath}",
"args": [
"make_settings_json.py"
],
"options": {
"cwd": "${workspaceFolder}/.vscode"
},
"runOptions": {
"runOn": "folderOpen"
},
"problemMatcher": []
}
]
}
2 changes: 1 addition & 1 deletion MANIFEST.in
Original file line number Diff line number Diff line change
@@ -1 +1 @@
graft webview
graft webview
27 changes: 27 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
ifeq ($(OS),Windows_NT)
PY = python
else
PY = python3
endif

all: dist

build:
$(PY) setup.py build

dist:
$(PY) setup.py sdist bdist_wheel

install:
$(PY) -m pip install .

test:
$(PY) test.py

upload:
$(PY) -m twine upload dist/*

clean:
$(RM) -r build dist *.egg-info *.dist-info __pycache__ *.pyc *.pyd *.so

.PHONY: all build dist install test upload clean
74 changes: 6 additions & 68 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,72 +1,10 @@
# webview
# webview-python

Python extension that provides API for the [webview] library.
Python extension that provides API for the [webview](https://github.com/webview/webview) library.

## Getting started

Install the bindings:
## TODO

```bash
pip install webview
```

Try the following example:

```python
import webview

w = webview.WebView(width=320, height=240, title="Hello", url="https://google.com", resizable=True, debug=False)
w.run()
```

You may use most of the webview APIs:

```python
# Change window title
w.set_title("New title")
# Make window fullscreen
w.set_fullscreen(True)
# Change initial window background color
w.set_color(255, 0, 0)
# Inject some JS
w.eval("alert('hello')")
# Inject some CSS
w.inject_css('* {background-color: yellow; }')
# Show native OS dialog
file_path = w.dialog(0, 0, "open file", "")
# Post funciton to the UI thread
w.dispatch(some_func)
w.dispatch(lambda: some_func())
# Control run loop
while w.loop(True):
pass
```

Dispatch is currently only a stub and is implemented as direct function call.
Also, proper Python-to-JS object mapping is not implemented yet, but is highly

## Development

To build and install the library locally:

```bash
python setup.py install
```

To upload a new version:

```bash
python setup.py sdist
twine upload dist/webview-*.tar.gz
```

To build and install it locally:

```bash
python setup.py install
```

Please, ensure that all sources are formatted using `yapf`.


[webview]: https://github.com/zserge/webview
- [ ] Figure out why `examples/with_server.py` doesn't work
- [ ] Better function binding support (automate `json.dumps` and `json.loads`)
- [ ] Remove support for Python 2.x
43 changes: 43 additions & 0 deletions examples/minimal.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import json
import time
from urllib.parse import quote

import webview


HTML = '''
This is a test<br/>
<div id="timestr">Time should tick here</div><br/>
<button onclick="quit();">Quit</button>
<script type="text/javascript">
timediv = document.getElementById('timestr');
updateTime = () => {
get_time('%Y-%m-%d %H:%M:%S').then((s) => {
timediv.innerHTML = s;
});
};
setInterval(updateTime, 1000);
updateTime();
</script>
'''


def get_time(w, req):
fmt = json.loads(req)[0]
return json.dumps(time.strftime(fmt))


def quit(w, req):
w.terminate()


def main():
w = webview.WebView(width=320, height=240, resizable=True, title="My App", debug=True)
w.bind('get_time', get_time)
w.bind('quit', quit)
w.navigate('data:text/html,' + quote(HTML))
w.run()


if __name__ == "__main__":
main()
71 changes: 71 additions & 0 deletions examples/with_server.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
import json
import random
import threading
import time
from http import HTTPStatus
from http.server import BaseHTTPRequestHandler, HTTPServer
from urllib.parse import quote
from itertools import count

import webview


HTML = '''
This is a test<br><button onclick="invoke('print_hello');">Click me</button>
'''


class MyHTTPRequestHandler(BaseHTTPRequestHandler):
def send_data(self, data, status=HTTPStatus.OK, mimetype='text/plain'):
if isinstance(data, str):
data = data.encode('utf8')
self.send_response(status)
self.send_header('Content-Type', mimetype)
self.send_header('Content-Length', len(data))
self.end_headers()
self.wfile.write(data)

def send_html(self, text):
self.send_data(text.encode('utf8'), mimetype='text/html')

def do_GET(self):
self.send_html(HTML)


def run_server():
while 1:
port = random.randint(20000, 30000)
try:
server = HTTPServer(('localhost', port), MyHTTPRequestHandler)
except Exception:
continue
break
threading.Thread(target=server.serve_forever, daemon=True).start()
return server


def callback(w, req):
# print(f'callback was called with {req!r}')
arg = json.loads(req)[0]
print(f'callback was called with {arg!r}')


def threadfunc():
for n in count():
print(n)
time.sleep(0.1)


def main():
s = run_server()
url = f'http://127.0.0.1:{s.server_port}'
print(url)
w = webview.WebView(width=320, height=240, title="My App", resizable=True, debug=True)
w.bind('invoke', callback)
w.navigate(url)
w.run()
s.shutdown()


if __name__ == "__main__":
main()
28 changes: 28 additions & 0 deletions pywebview.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import argparse
import os

import webview


def main():
p = argparse.ArgumentParser(formatter_class=argparse.ArgumentDefaultsHelpFormatter)
p.add_argument('url')
p.add_argument('-s', '--size', default='800x600', help='Window size in the form <WIDTH>x<HEIGHT>')
p.add_argument('-f', '--fixed-size', action='store_true', help='Makes the window non-resizable')
p.add_argument('-t', '--title', default='Webview', help='Set the window title')
args = p.parse_args()

try:
width, height = map(int, args.size.split('x'))
except Exception:
p.error('Size must be of the form <WIDTH>x<HEIGHT>')

if not os.path.exists(args.url) and '://' not in args.url:
args.url = 'http://' + args.url

w = webview.WebView(width, height, resizable=not args.fixed_size, url=args.url, title=args.title)
w.run()


if __name__ == "__main__":
main()
Loading