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

Add Pygal on GraalPy demos. #6

Merged
merged 8 commits into from
Oct 7, 2024
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
4 changes: 2 additions & 2 deletions .github/workflows/graalpy-micronaut-guide.yml
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ jobs:
./mvnw --no-transfer-progress mn:run &
mnpid="$!"
sleep 30
curl -s -D - -o /dev/null http://localhost:8080/
curl --fail-with-body --silent --dump-header - -o /dev/null http://localhost:8080/
kill $mnpid
- name: Build and run native 'graalpy-micronaut-guide' using Maven
run: |
Expand All @@ -43,5 +43,5 @@ jobs:
./target/graalpy-micronaut &
mnpid="$!"
sleep 20
curl -s -D - -o /dev/null http://localhost:8080/
curl --fail-with-body --silent --dump-header - -o /dev/null http://localhost:8080/
kill $mnpid
47 changes: 47 additions & 0 deletions .github/workflows/graalpy-micronaut-pygal-charts.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
name: Test GraalPy Micronaut Pygal Charts
on:
push:
paths:
- 'graalpy/graalpy-micronaut-pygal-charts/**'
- '.github/workflows/graalpy-micronaut-pygal-charts.yml'
pull_request:
paths:
- 'graalpy/graalpy-micronaut-pygal-charts/**'
- '.github/workflows/graalpy-micronaut-pygal-charts.yml'
workflow_dispatch:
permissions:
contents: read
env:
NATIVE_IMAGE_OPTIONS: '-J-Xmx16g'
jobs:
run:
name: 'graalpy-micronaut-pygal-charts'
runs-on: ubuntu-latest
timeout-minutes: 30
steps:
- uses: actions/checkout@v4
- uses: graalvm/setup-graalvm@v1
with:
java-version: '23.0.0'
distribution: 'graalvm'
github-token: ${{ secrets.GITHUB_TOKEN }}
cache: 'maven'
native-image-job-reports: 'true'
- name: Build, test, and run 'graalpy-micronaut-pygal-charts' using Maven
run: |
cd graalpy/graalpy-micronaut-pygal-charts
./mvnw --no-transfer-progress clean test -Dmicronaut.http.client.read-timeout=1m
./mvnw --no-transfer-progress mn:run &
mnpid="$!"
sleep 30
curl --fail-with-body --fail-with-body --silent --dump-header - -o /dev/null http://localhost:8080/java
kill $mnpid
- name: Build and run native 'graalpy-micronaut-pygal-charts' using Maven
run: |
cd graalpy/graalpy-micronaut-pygal-charts
./mvnw --no-transfer-progress clean package -DskipTests -Dpackaging=native-image
./target/demo &
mnpid="$!"
sleep 20
curl --fail-with-body --fail-with-body --silent --dump-header - -o /dev/null http://localhost:8080/python
kill $mnpid
4 changes: 2 additions & 2 deletions .github/workflows/graalpy-spring-boot-guide.yml
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ jobs:
./mvnw --no-transfer-progress spring-boot:run &
sbpid="$!"
sleep 30
curl -s -D - -o /dev/null http://localhost:8080/
curl --fail-with-body --silent --dump-header - -o /dev/null http://localhost:8080/
kill $sbpid
- name: Build and run native 'graalpy-spring-boot-guide' using Maven
run: |
Expand All @@ -43,5 +43,5 @@ jobs:
./target/graalpy-springboot &
sbpid="$!"
sleep 20
curl -s -D - -o /dev/null http://localhost:8080/
curl --fail-with-body --silent --dump-header - -o /dev/null http://localhost:8080/
kill $sbpid
47 changes: 47 additions & 0 deletions .github/workflows/graalpy-spring-boot-pygal-charts.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
name: Test GraalPy Spring Pygal Charts
on:
push:
paths:
- 'graalpy/graalpy-spring-boot-pygal-charts/**'
- '.github/workflows/graalpy-spring-boot-pygal-charts.yml'
pull_request:
paths:
- 'graalpy/graalpy-spring-boot-pygal-charts/**'
- '.github/workflows/graalpy-spring-boot-pygal-charts.yml'
workflow_dispatch:
permissions:
contents: read
env:
NATIVE_IMAGE_OPTIONS: '-J-Xmx16g'
jobs:
run:
name: 'graalpy-spring-boot-pygal-charts'
runs-on: ubuntu-latest
timeout-minutes: 30
steps:
- uses: actions/checkout@v4
- uses: graalvm/setup-graalvm@v1
with:
java-version: '23.0.0'
distribution: 'graalvm'
github-token: ${{ secrets.GITHUB_TOKEN }}
cache: 'maven'
native-image-job-reports: 'true'
- name: Build, test, and run 'graalpy-spring-boot-pygal-charts' using Maven
run: |
cd graalpy/graalpy-spring-boot-pygal-charts
./mvnw --no-transfer-progress clean test -Dspring.mvc.async.request-timeout=60000
./mvnw --no-transfer-progress spring-boot:run &
sbpid="$!"
sleep 30
curl --fail-with-body --silent --dump-header - -o /dev/null http://localhost:8080/java
kill $sbpid
- name: Build and run native 'graalpy-spring-boot-pygal-charts' using Maven
run: |
cd graalpy/graalpy-spring-boot-pygal-charts
./mvnw --no-transfer-progress clean -DskipTests -Pnative native:compile
./target/demo &
sbpid="$!"
sleep 20
curl --fail-with-body --silent --dump-header - -o /dev/null http://localhost:8080/python
kill $sbpid
2 changes: 1 addition & 1 deletion .github/workflows/graalwasm-micronaut-photon.yml
Original file line number Diff line number Diff line change
Expand Up @@ -35,4 +35,4 @@ jobs:
./mvnw --no-transfer-progress clean package -Dpackaging=native-image
./target/demo &
sleep 10
curl -s -D - -o /dev/null http://localhost:8080/photo/flipv
curl --fail-with-body --silent --dump-header - -o /dev/null http://localhost:8080/photo/flipv
2 changes: 1 addition & 1 deletion .github/workflows/graalwasm-spring-boot-photon.yml
Original file line number Diff line number Diff line change
Expand Up @@ -35,4 +35,4 @@ jobs:
./mvnw --no-transfer-progress clean -Pnative native:compile
./target/demo &
sleep 10
curl -s -D - -o /dev/null http://localhost:8080/photo/flipv
curl --fail-with-body --silent --dump-header - -o /dev/null http://localhost:8080/photo/flipv
2 changes: 2 additions & 0 deletions graalpy/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ This directory contains demo applications and guides for [GraalPy](https://www.g
- [Minimal Java application that embeds GraalPy](graalpy-starter/)
- [Minimal Java application that embeds `openai` Python package with GraalPy](graalpy-openai-starter/)
- [Embed `qrcode` Python package with GraalPy in JBang](graalpy-jbang-qrcode/)
- [Embed SVG charting library `pygal` with GraalPy in Micronaut](graalpy-micronaut-pygal-charts/)
- [Embed SVG charting library `pygal` with GraalPy in Spring Boot](graalpy-spring-boot-pygal-charts/)

## Guides

Expand Down
15 changes: 15 additions & 0 deletions graalpy/graalpy-micronaut-pygal-charts/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
Thumbs.db
.DS_Store
.gradle
build/
target/
out/
.micronaut/
.idea
*.iml
*.ipr
*.iws
.project
.settings
.classpath
.factorypath
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
wrapperVersion=3.3.2
distributionType=only-script
distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.9/apache-maven-3.9.9-bin.zip
48 changes: 48 additions & 0 deletions graalpy/graalpy-micronaut-pygal-charts/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
## SVG Charts with GraalPy and Micronaut

This demo illustrates how GraalPy can be used to embed [Pygal](https://github.com/Kozea/pygal), a dynamic SVG charting library written in Python, in a Micronaut application.
In particular, this demo shows four different approaches to interact with Pygal from Java.

## Preparation

Install GraalVM for JDK 23 and set the value of `JAVA_HOME` accordingly.
We recommend using [SDKMAN!](https://sdkman.io/). (For other download options, see [GraalVM Downloads](https://www.graalvm.org/downloads/).)

```bash
sdk install java 23-graal
```

## Run the Application

To start the demo, simply run:

```bash
./mvnw package mn:run
```

When the demo runs, open the follwing URLs in a browser:

| URL | Service |
|:------------------------------|:------------------------------|
| http://localhost:8080/java | [`PyGalServicePureJava`](src/main/java/com/example/PyGalServicePureJava.java) |
| http://localhost:8080/python | [`PyGalServicePurePython`](src/main/java/com/example/PyGalServicePurePython.java) |
| http://localhost:8080/mixed | [`PyGalServiceMixed`](src/main/java/com/example/PyGalServiceMixed.java) |
| http://localhost:8080/dynamic | [`PyGalServiceValueAPIDynamic`](src/main/java/com/example/PyGalServiceValueAPIDynamic.java) |


## Implementation Details

The `DemoController` uses four services that all render the same XY chart using different implementations:

- [`PyGalServicePureJava`](src/main/java/com/example/PyGalServicePureJava.java) interacts with Pygal and Python using Java interfaces and `Value.as(Class<T> targetType)`. This is the recommended approach.
- [`PyGalServicePurePython`](src/main/java/com/example/PyGalServicePurePython.java) embeds the Python sample code from the Pygal documentation.
- [`PyGalServiceMixed`](src/main/java/com/example/PyGalServiceMixed.java) uses a Python function which is invoked with Java values.
- [`PyGalServiceValueAPIDynamic`](src/main/java/com/example/PyGalServiceValueAPIDynamic.java) uses the [Value](https://www.graalvm.org/sdk/javadoc/org/graalvm/polyglot/Value.html) API from the GraalVM SDK.


The `DemoTest` ensures that all four service implementations render the same XY chart. Run it with `./mvnw test`.

> Note: This demo uses a single [`GraalPyContext`](src/main/java/com/example/GraalPyContext.java), which can execute [Python code in only one thread at a time](https://docs.python.org/3/glossary.html#term-global-interpreter-lock).
> Threads running Python code are internally scheduled in round-robin fashion.
> Pure Python packages including Pygal can be used in multiple GraalPy contexts, for example one context per thread, to improve the throughput of the application.
> Other demos such as [`graalwasm-micronaut-photon`](../graalwasm/graalwasm/graalwasm-micronaut-photon) illustrate how to pool multiple contexts.
37 changes: 37 additions & 0 deletions graalpy/graalpy-micronaut-pygal-charts/aot-jar.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# AOT configuration properties for jar packaging
# Please review carefully the optimizations enabled below
# Check https://micronaut-projects.github.io/micronaut-aot/latest/guide/ for more details

# Caches environment property values: environment properties will be deemed immutable after application startup.
cached.environment.enabled=true

# Precomputes Micronaut configuration property keys from the current environment variables
precompute.environment.properties.enabled=true

# Replaces logback.xml with a pure Java configuration
logback.xml.to.java.enabled=true

# Converts YAML configuration files to Java configuration
yaml.to.java.config.enabled=true

# Scans for service types ahead-of-time, avoiding classpath scanning at startup
serviceloading.jit.enabled=true

# Scans reactive types at build time instead of runtime
scan.reactive.types.enabled=true

# Deduces the environment at build time instead of runtime
deduce.environment.enabled=true

# Checks for the existence of some types at build time instead of runtime
known.missing.types.enabled=true

# Precomputes property sources at build time
sealed.property.source.enabled=true

# The list of service types to be scanned (comma separated)
service.types=io.micronaut.context.env.PropertySourceLoader,io.micronaut.inject.BeanConfiguration,io.micronaut.inject.BeanDefinitionReference,io.micronaut.http.HttpRequestFactory,io.micronaut.http.HttpResponseFactory,io.micronaut.core.beans.BeanIntrospectionReference,io.micronaut.core.convert.TypeConverterRegistrar,io.micronaut.context.env.PropertyExpressionResolver

# A list of types that the AOT analyzer needs to check for existence (comma separated)
known.missing.types.list=io.reactivex.Observable,reactor.core.publisher.Flux,kotlinx.coroutines.flow.Flow,io.reactivex.rxjava3.core.Flowable,io.reactivex.rxjava3.core.Observable,io.reactivex.Single,reactor.core.publisher.Mono,io.reactivex.Maybe,io.reactivex.rxjava3.core.Single,io.reactivex.rxjava3.core.Maybe,io.reactivex.Completable,io.reactivex.rxjava3.core.Completable,io.methvin.watchservice.MacOSXListeningWatchService,io.micronaut.core.async.publisher.CompletableFuturePublisher,io.micronaut.core.async.publisher.Publishers.JustPublisher,io.micronaut.core.async.subscriber.Completable

6 changes: 6 additions & 0 deletions graalpy/graalpy-micronaut-pygal-charts/micronaut-cli.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
applicationType: default
defaultPackage: com.example
testFramework: junit
sourceLanguage: java
buildTool: maven
features: [app-name, http-client-test, java, java-application, junit, logback, maven, maven-enforcer-plugin, micronaut-aot, micronaut-http-validation, netty-server, properties, readme, serialization-jackson, shade, static-resources]
Loading