Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 1 addition & 1 deletion src/pyscript/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@
import platformdirs
from rich.console import Console

LATEST_PYSCRIPT_VERSION = "2022.12.1"
APPNAME = "pyscript"
APPAUTHOR = "python"
DEFAULT_CONFIG_FILENAME = ".pyscriptconfig"


# Default initial data for the command line.
DEFAULT_CONFIG = {
# Name of config file for PyScript projects.
Expand Down
26 changes: 21 additions & 5 deletions src/pyscript/_generator.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
import jinja2
import toml

from pyscript import config
from pyscript import LATEST_PYSCRIPT_VERSION, config

_env = jinja2.Environment(loader=jinja2.PackageLoader("pyscript"))
TEMPLATE_PYTHON_CODE = """# Replace the code below with your own
Expand All @@ -15,7 +15,11 @@


def create_project_html(
title: str, python_file_path: str, config_file_path: str, output_file_path: Path
title: str,
python_file_path: str,
config_file_path: str,
output_file_path: Path,
pyscript_version: str = LATEST_PYSCRIPT_VERSION,
) -> None:
"""Write a Python script string to an HTML file template."""
template = _env.get_template("basic.html")
Expand All @@ -25,6 +29,7 @@ def create_project_html(
python_file_path=python_file_path,
config_file_path=config_file_path,
title=title,
pyscript_version=pyscript_version,
)
)

Expand All @@ -49,7 +54,11 @@ def save_config_file(config_file: Path, configuration: dict):


def string_to_html(
code: str, title: str, output_path: Path, template_name: str = "basic.html"
code: str,
title: str,
output_path: Path,
template_name: str = "basic.html",
pyscript_version: str = LATEST_PYSCRIPT_VERSION,
) -> None:
"""Write a Python script string to an HTML file template.

Expand All @@ -59,33 +68,39 @@ def string_to_html(
PyScript app template
- title(str): application title, that will be placed as title of the html
app template
- output_path(Path): path where to write the new html file
- template_name(str): name of the template to be used
- pyscript_version(str): version of pyscript to be used

Output:
(None)
"""
template = _env.get_template(template_name)
with output_path.open("w") as fp:
fp.write(template.render(code=code, title=title))
fp.write(
template.render(code=code, title=title, pyscript_version=pyscript_version)
)


def file_to_html(
input_path: Path,
title: str,
output_path: Optional[Path],
template_name: str = "basic.html",
pyscript_version: str = LATEST_PYSCRIPT_VERSION,
) -> None:
"""Write a Python script string to an HTML file template."""
output_path = output_path or input_path.with_suffix(".html")
with input_path.open("r") as fp:
string_to_html(fp.read(), title, output_path, template_name)
string_to_html(fp.read(), title, output_path, template_name, pyscript_version)


def create_project(
app_name: str,
app_description: str,
author_name: str,
author_email: str,
pyscript_version: str = LATEST_PYSCRIPT_VERSION,
) -> None:
"""
New files created:
Expand Down Expand Up @@ -124,4 +139,5 @@ def create_project(
config["project_main_filename"],
config["project_config_filename"],
index_file,
pyscript_version=pyscript_version,
)
11 changes: 9 additions & 2 deletions src/pyscript/plugins/create.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from pyscript import app, cli, plugins
from pyscript import LATEST_PYSCRIPT_VERSION, app, cli, plugins
from pyscript._generator import create_project

try:
Expand All @@ -13,6 +13,11 @@ def create(
app_description: str = typer.Option(..., prompt=True),
author_name: str = typer.Option(..., prompt=True),
author_email: str = typer.Option(..., prompt=True),
pyscript_version: str = typer.Option(
LATEST_PYSCRIPT_VERSION,
"--pyscript-version",
help="If provided, defines what version of pyscript will be used to create the app",
),
):
"""
Create a new pyscript project with the passed in name, creating a new
Expand All @@ -21,7 +26,9 @@ def create(
TODO: Agree on the metadata to be collected from the user.
"""
try:
create_project(app_name, app_description, author_name, author_email)
create_project(
app_name, app_description, author_name, author_email, pyscript_version
)
except FileExistsError:
raise cli.Abort(
f"A directory called {app_name} already exists in this location."
Expand Down
23 changes: 20 additions & 3 deletions src/pyscript/plugins/wrap.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
from pathlib import Path
from typing import Optional

from pyscript import app, cli, console, plugins
from pyscript import LATEST_PYSCRIPT_VERSION, app, cli, console, plugins
from pyscript._generator import file_to_html, string_to_html

try:
Expand All @@ -29,6 +29,11 @@ def wrap(
),
show: Optional[bool] = typer.Option(None, help="Open output file in web browser."),
title: Optional[str] = typer.Option(None, help="Add title to HTML file."),
pyscript_version: str = typer.Option(
LATEST_PYSCRIPT_VERSION,
"--pyscript-version",
help="If provided, defines what version of pyscript will be used to create the app",
),
) -> None:
"""Wrap a Python script inside an HTML file."""
title = title or "PyScript App"
Expand All @@ -52,9 +57,21 @@ def wrap(
else:
raise cli.Abort("Must provide an output file or use `--show` option")
if input_file is not None:
file_to_html(input_file, title, output, template_name="wrap.html")
file_to_html(
input_file,
title,
output,
template_name="wrap.html",
pyscript_version=pyscript_version,
)
if command:
string_to_html(command, title, output, template_name="wrap.html")
string_to_html(
command,
title,
output,
template_name="wrap.html",
pyscript_version=pyscript_version,
)
if output:
if show:
console.print("Opening in web browser!")
Expand Down
4 changes: 2 additions & 2 deletions src/pyscript/templates/basic.html
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
<html lang="en">
<head>
<title>{{ title }}</title>
<link rel="stylesheet" href="https://pyscript.net/alpha/pyscript.css"/>
<script defer src="https://pyscript.net/alpha/pyscript.js"></script>
<link rel="stylesheet" href="https://pyscript.net/releases/{{ pyscript_version }}/pyscript.css"/>
<script defer src="https://pyscript.net/releases/{{ pyscript_version }}/pyscript.js"></script>
</head>
<body>
<py-config src="./{{ config_file_path }}"></py-config>
Expand Down
4 changes: 2 additions & 2 deletions src/pyscript/templates/wrap.html
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
<html lang="en">
<head>
<title>{{ title }}</title>
<link rel="stylesheet" href="https://pyscript.net/alpha/pyscript.css"/>
<script defer src="https://pyscript.net/alpha/pyscript.js"></script>
<link rel="stylesheet" href="https://pyscript.net/releases/{{ pyscript_version }}/pyscript.css"/>
<script defer src="https://pyscript.net/releases/{{ pyscript_version }}/pyscript.js"></script>
</head>
<body>
<py-script>
Expand Down
165 changes: 164 additions & 1 deletion tests/test_cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
from mypy_extensions import VarArg
from typer.testing import CliRunner, Result

from pyscript import __version__
from pyscript import LATEST_PYSCRIPT_VERSION, __version__, config
from pyscript.cli import app

if TYPE_CHECKING:
Expand Down Expand Up @@ -167,3 +167,166 @@ def test_wrap_title(
assert f"<py-script>\n{command}\n</py-script>" in html_text

assert f"<title>{expected_title}</title>" in html_text


@pytest.mark.parametrize(
"version, expected_version",
[(None, LATEST_PYSCRIPT_VERSION), ("2022.9.1", "2022.9.1")],
)
def test_wrap_pyscript_version(
invoke_cli: CLIInvoker,
version: Optional[str],
expected_version: str,
tmp_path: Path,
) -> None:
"""
Test that when wrap is called passing a string code input and an explicit pyscript version
the project is created correctly
"""
command = 'print("Hello World!")'
args = ["wrap", "-c", command, "-o", "output.html"]
if version is not None:
args.extend(["--pyscript-version", version])

# GIVEN a call to wrap with a cmd input and specific pyscript version as arguments
result = invoke_cli(*args)
assert result.exit_code == 0

# EXPECT the output file to exist
expected_html_path = tmp_path / "output.html"
assert expected_html_path.exists()

with expected_html_path.open() as fp:
html_text = fp.read()

# EXPECT the right cmd to be present in the output file
assert f"<py-script>\n{command}\n</py-script>" in html_text

# EXPECT the right JS and CSS version to be present in the output file
version_str = (
f'<script defer src="https://pyscript.net/releases/{expected_version}'
'/pyscript.js"></script>'
)
css_version_str = (
'<link rel="stylesheet" href="https://pyscript.net/releases/'
f'{expected_version}/pyscript.css"/>'
)
assert version_str in html_text
assert css_version_str in html_text


@pytest.mark.parametrize(
"version, expected_version",
[(None, LATEST_PYSCRIPT_VERSION), ("2022.9.1", "2022.9.1")],
)
def test_wrap_pyscript_version_file(
invoke_cli: CLIInvoker,
version: Optional[str],
expected_version: str,
tmp_path: Path,
) -> None:
"""
Test that when wrap is called passing a file input and an explicit pyscript version
the project is created correctly
"""
command = 'print("Hello World!")'
input_file = tmp_path / "hello.py"
with input_file.open("w") as fp:
fp.write(command)

args = ["wrap", str(input_file), "-o", "output.html"]

if version is not None:
args.extend(["--pyscript-version", version])

# GIVEN a call to wrap with a file and specific pyscript version as arguments
result = invoke_cli(*args)
assert result.exit_code == 0

# EXPECT the output file to exist
expected_html_path = tmp_path / "output.html"
assert expected_html_path.exists()

with expected_html_path.open() as fp:
html_text = fp.read()

# EXPECT the right cmd to be present in the output file
assert f"<py-script>\n{command}\n</py-script>" in html_text

# EXPECT the right JS and CSS version to be present in the output file
version_str = (
f'<script defer src="https://pyscript.net/releases/{expected_version}'
'/pyscript.js"></script>'
)
css_version_str = (
'<link rel="stylesheet" href="https://pyscript.net/releases/'
f'{expected_version}/pyscript.css"/>'
)
assert version_str in html_text
assert css_version_str in html_text


@pytest.mark.parametrize(
"create_args, expected_version",
[
(("myapp1",), LATEST_PYSCRIPT_VERSION),
(("myapp-w-version", "--pyscript-version", "2022.9.1"), "2022.9.1"),
],
)
def test_create_project_version(
invoke_cli: CLIInvoker,
tmp_path: Path,
create_args: tuple[str],
expected_version: str,
) -> None:
"""
Test that project created with an explicit pyscript version are created correctly
"""
command = 'print("Hello World!")'

input_file = tmp_path / "hello.py"
with input_file.open("w") as fp:
fp.write(command)

cmd_args = list(create_args) + [
"--app-description",
"",
"--author-name",
"tester",
"--author-email",
"tester@me.com",
]

# GIVEN a call to wrap with a file and specific pyscript version as arguments
result = invoke_cli("create", *cmd_args)
assert result.exit_code == 0

# EXPECT the app folder to exist
expected_app_path = tmp_path / create_args[0]
assert expected_app_path.exists()

# EXPECT the app folder to contain the right index.html file
app_file = expected_app_path / "index.html"
assert app_file.exists()
with app_file.open() as fp:
html_text = fp.read()

# EXPECT the right JS and CSS version to be present in the html file
version_str = (
f'<script defer src="https://pyscript.net/releases/{expected_version}'
'/pyscript.js"></script>'
)
css_version_str = (
'<link rel="stylesheet" href="https://pyscript.net/releases/'
f'{expected_version}/pyscript.css"/>'
)
assert version_str in html_text
assert css_version_str in html_text

# EXPECT the folder to also contain the python main file
py_file = expected_app_path / config["project_main_filename"]
assert py_file.exists()

# EXPECT the folder to also contain the config file
config_file = expected_app_path / config["project_config_filename"]
assert config_file.exists()