Skip to content

Commit ec3b9fd

Browse files
authored
Initial commit
0 parents  commit ec3b9fd

32 files changed

+2876
-0
lines changed

.devcontainer/devcontainer.json

+36
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
// For format details, see https://aka.ms/devcontainer.json. For config options, see the
2+
// README at: https://github.com/devcontainers/templates/tree/main/src/python
3+
{
4+
"name": "Python 3",
5+
// Or use a Dockerfile or Docker Compose file. More info: https://containers.dev/guide/dockerfile
6+
"image": "mcr.microsoft.com/devcontainers/python:3.10-bullseye",
7+
8+
// Features to add to the dev container. More info: https://containers.dev/features.
9+
"features": {
10+
"ghcr.io/devcontainers-contrib/features/poetry:2": {},
11+
"ghcr.io/devcontainers/features/node:1": {}
12+
},
13+
14+
// Use 'forwardPorts' to make a list of ports inside the container available locally.
15+
// "forwardPorts": [],
16+
17+
// Use 'postCreateCommand' to run commands after the container is created.
18+
"postCreateCommand": "poetry install && poetry run playwright install --with-deps",
19+
20+
// Configure tool-specific properties.
21+
"customizations": {
22+
"vscode": {
23+
"extensions": [
24+
"ms-python.python",
25+
"ms-toolsai.jupyter",
26+
"charliermarsh.ruff",
27+
"streetsidesoftware.code-spell-checker",
28+
"tamasfe.even-better-toml",
29+
"ryanluker.vscode-coverage-gutters"
30+
]
31+
}
32+
}
33+
34+
// Uncomment to connect as root instead. More info: https://aka.ms/dev-containers-non-root.
35+
// "remoteUser": "root"
36+
}

.github/workflows/main.yaml

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
name: 'Validate Tapyr App'
2+
on:
3+
pull_request:
4+
push:
5+
branches:
6+
- main
7+
8+
jobs:
9+
test:
10+
runs-on: ubuntu-latest
11+
steps:
12+
- name: Checkout (GitHub)
13+
uses: actions/checkout@v4
14+
15+
- name: Run quality checks
16+
uses: devcontainers/ci@v0.3
17+
with:
18+
runCmd: ./quality_checks.sh

.github/workflows/pre-commit.yml

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
name: pre-commit
2+
3+
on:
4+
pull_request:
5+
push:
6+
branches: [main]
7+
8+
jobs:
9+
pre-commit:
10+
runs-on: ubuntu-latest
11+
steps:
12+
- uses: actions/checkout@v4
13+
- uses: actions/setup-python@v5
14+
- uses: pre-commit/action@v3.0.1

.gitignore

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
__pycache__
2+
.ipynb_checkpoints
3+
.DS_Store
4+
5+
# Code coverage
6+
lcov.info
7+
.coverage
8+
9+
# Results of playwright tests with tracing
10+
test-results/
11+
12+
# Files from playwright installed with npm
13+
node_modules
14+
package-lock.json
15+
package.json

.pre-commit-config.yaml

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
repos:
2+
- repo: https://github.com/pre-commit/pre-commit-hooks
3+
rev: v4.5.0
4+
hooks:
5+
- id: trailing-whitespace
6+
- id: end-of-file-fixer
7+
- id: check-yaml
8+
- id: check-added-large-files
9+
exclude: ^data/records\.parquet$
10+
11+
- repo: https://github.com/astral-sh/ruff-pre-commit
12+
rev: v0.4.1
13+
hooks:
14+
- id: ruff
15+
args: [ --fix ]
16+
- id: ruff-format

.vscode/settings.json

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"python.testing.pytestArgs": [
3+
"tests"
4+
],
5+
"python.testing.unittestEnabled": false,
6+
"python.testing.pytestEnabled": true
7+
}

LICENSE

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2024 Appsilon
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

README.md

+105
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
# Tapyr - Shiny for Python Application Template<a href="https://appsilon.github.io/tapyr-template/"><img src="www/images/tapyr.png" align="right" alt="Tapyr logo" style="height: 140px;"></a>
2+
3+
> Create and deploy enterprise-ready PyShiny dashboards with ease.
4+
5+
## Introduction
6+
7+
Tapyr is designed for data scientists and developers seeking a seamless transition from development to deployment, this template uses `poetry` for dependency management and `pytest`/`playwright` for comprehensive app validation/testing/quality assurance.
8+
Ideal for projects aiming for high-quality code and efficient deployment on Posit Connect.
9+
10+
## Events
11+
### Upcoming
12+
Would you like to learn about Tapyr? Join our events!
13+
* [**Open Source Spotlight: Tapyr - Shiny for Python Framework**](https://go.appsilon.com/tapyr-webinar-may2024?utm_source=community&utm_medium=github&utm_campaign=shinygathering)<br>
14+
2024-05-28 at 18:00 (UTC+1)<br>
15+
Shiny Gathering led by [Piotr Storożenko](https://www.linkedin.com/in/piotr-pasza-storo%C5%BCenko/)
16+
17+
## Docs
18+
19+
For comprehensive documentation, please visit our [documentation](https://connect.appsilon.com/tapyr-docs/).
20+
21+
## Getting Started
22+
23+
Check out our get started with `tapyr` [blog post](www.appsilon.com/post/introducing-tapyr).
24+
25+
### Using Devcontainer
26+
27+
To ensure a consistent development experience across all environments, we recommend using the [devcontainer](https://code.visualstudio.com/docs/remote/containers) configuration with Visual Studio Code or DevPod for container-based development.
28+
29+
1. **Start the Devcontainer**: Open the project in VS Code and select "Reopen in Container" when prompted, or use the Command Palette (`Ctrl+Shift+P`) and choose "Remote-Containers: Reopen in Container". Alternatively, use [DevPod](https://devpod.sh/) following their instructions.
30+
2. **Activate the virtual environment**:
31+
```sh
32+
poetry shell
33+
```
34+
3. **Run the application**:
35+
```sh
36+
shiny run app.py --reload
37+
```
38+
4. **Execute tests**:
39+
```sh
40+
poetry run pytest
41+
```
42+
43+
*Note*: The Devcontainer might limit some `playwright` features, such as `codegen`. For full functionality, consider a local setup.
44+
45+
### Setting Up Locally with Poetry
46+
47+
For developers preferring a local setup without Devcontainer:
48+
49+
1. **Install pipx**: Ensure pipx is installed for managing isolated CLI apps.
50+
2. **Install Poetry**:
51+
```sh
52+
pipx install poetry
53+
```
54+
3. **Clone the repository** and navigate to it.
55+
4. **Install dependencies**:
56+
```sh
57+
poetry install
58+
playwright install
59+
```
60+
61+
*Attention*: Follow any additional steps prompted by `playwright install`.
62+
63+
### Deployment on Posit Connect
64+
65+
Deploy your application to Posit Connect by:
66+
67+
1. **Exporting your API Key**:
68+
```sh
69+
export CONNECT_API_KEY="your_api_key_here"
70+
```
71+
2. **Configuring Posit Connect**:
72+
```sh
73+
rsconnect add \
74+
--api-key $CONNECT_API_KEY \
75+
--server <MY_CONNECT_URL> \
76+
--name <SERVER_NAME>
77+
```
78+
3. **Deploying**:
79+
```sh
80+
rsconnect deploy shiny -t "Tapyr App" .
81+
```
82+
83+
Replace placeholders with your server URL, server name, and API key. Verify the deployment on Posit Connect for successful upload.
84+
85+
## :star2: Stay Updated
86+
Don't miss out on important updates and exclusive content about Tapyr and PyShiny → [Subscribe to our newsletter](https://go.appsilon.com/shiny-weekly?utm_source=community&utm_medium=github&utm_content=tapyr).
87+
88+
Have questions or want to contribute? Engage with Appsilon's developers and the data science community on our [Shiny 4 All](https://go.appsilon.com/shiny4allcommunity).
89+
90+
91+
---
92+
93+
Developed with :heart: at [Appsilon](https://appsilon.com).
94+
Get in touch: <opensource@appsilon.com>.
95+
96+
Want to stay up to date with Tapyr and other packages? Join 4,2k explorers and get the [📧 Shiny Weekly Newsletter](https://go.appsilon.com/shiny-weekly?utm_source=community&utm_medium=github&utm_content=tapyr) into your mailbox and check our [Slack community](https://go.appsilon.com/shiny4allcommunity).
97+
98+
Explore the [Rhinoverse](https://rhinoverse.dev) - a family of R packages built around [Rhino](https://appsilon.github.io/rhino/)!
99+
100+
Appsilon is a
101+
[**Posit (formerly RStudio) Full Service Certified Partner**](https://www.rstudio.com/certified-partners/).
102+
103+
<a href="https://appsilon.com/careers/">
104+
<img src="https://raw.githubusercontent.com/Appsilon/website-cdn/gh-pages/WeAreHiring1.png" alt="We are hiring!">
105+
</a>

app.py

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import sys
2+
from pathlib import Path
3+
4+
from loguru import logger
5+
from shiny import App, ui
6+
7+
from tapyr_template.settings import AppSettings
8+
from tapyr_template.view.root import get_dashboard_ui, server
9+
10+
# Setup settings and logger
11+
app_settings = AppSettings()
12+
logger.remove()
13+
logger.add(sys.stderr, level=app_settings.log_level)
14+
15+
# Combine clean shiny UI with CSS and external resources
16+
ui_with_css = ui.TagList(ui.tags.link(href="style.css", rel="stylesheet"), get_dashboard_ui())
17+
18+
app_dir = Path(__file__).parent
19+
app = App(ui_with_css, server, static_assets=app_dir / "www")

notebooks/01_experiments.ipynb

+69
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
{
2+
"cells": [
3+
{
4+
"cell_type": "code",
5+
"execution_count": null,
6+
"metadata": {},
7+
"outputs": [],
8+
"source": [
9+
"%load_ext autoreload\n",
10+
"%autoreload 2"
11+
]
12+
},
13+
{
14+
"cell_type": "code",
15+
"execution_count": null,
16+
"metadata": {},
17+
"outputs": [],
18+
"source": [
19+
"from tapyr_template.logic.utils import divide"
20+
]
21+
},
22+
{
23+
"cell_type": "code",
24+
"execution_count": null,
25+
"metadata": {},
26+
"outputs": [],
27+
"source": [
28+
"divide(10, 2)"
29+
]
30+
},
31+
{
32+
"cell_type": "code",
33+
"execution_count": null,
34+
"metadata": {},
35+
"outputs": [],
36+
"source": [
37+
"# divide(10, 0) # raises ZeroDivisionError"
38+
]
39+
},
40+
{
41+
"cell_type": "code",
42+
"execution_count": null,
43+
"metadata": {},
44+
"outputs": [],
45+
"source": []
46+
}
47+
],
48+
"metadata": {
49+
"kernelspec": {
50+
"display_name": "pyshiny-template-AF2zGnGe-py3.12",
51+
"language": "python",
52+
"name": "python3"
53+
},
54+
"language_info": {
55+
"codemirror_mode": {
56+
"name": "ipython",
57+
"version": 3
58+
},
59+
"file_extension": ".py",
60+
"mimetype": "text/x-python",
61+
"name": "python",
62+
"nbconvert_exporter": "python",
63+
"pygments_lexer": "ipython3",
64+
"version": "3.12.3"
65+
}
66+
},
67+
"nbformat": 4,
68+
"nbformat_minor": 2
69+
}

0 commit comments

Comments
 (0)