This is an automated email from the ASF dual-hosted git repository.

dongjoon pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/spark-connect-swift.git


The following commit(s) were added to refs/heads/main by this push:
     new a9b267e  [SPARK-52067] Add `Examples` directory
a9b267e is described below

commit a9b267eae59e7b4327ef5c90d178a965a3f01dfc
Author: Dongjoon Hyun <[email protected]>
AuthorDate: Sat May 10 10:20:18 2025 -0700

    [SPARK-52067] Add `Examples` directory
    
    ### What changes were proposed in this pull request?
    
    This PR aims to add `Examples` directory.
    
    ### Why are the changes needed?
    
    To provide ASF-licensed examples officially.
    
    ### Does this PR introduce _any_ user-facing change?
    
    No.
    
    ### How was this patch tested?
    
    Manual review.
    
    ### Was this patch authored or co-authored using generative AI tooling?
    
    No.
    
    Closes #124 from dongjoon-hyun/SPARK-52067.
    
    Authored-by: Dongjoon Hyun <[email protected]>
    Signed-off-by: Dongjoon Hyun <[email protected]>
---
 Examples/app/Package.swift                         | 37 +++++++++
 Examples/app/README.md                             | 33 ++++++++
 Examples/app/Sources/main.swift                    | 41 ++++++++++
 Examples/web/Package.swift                         | 52 +++++++++++++
 Examples/web/README.md                             | 89 ++++++++++++++++++++++
 .../Sources/SparkConnectSwiftWeb/configure.swift   | 26 +++++++
 .../Sources/SparkConnectSwiftWeb/entrypoint.swift  | 50 ++++++++++++
 .../web/Sources/SparkConnectSwiftWeb/routes.swift  | 40 ++++++++++
 README.md                                          |  5 +-
 9 files changed, 369 insertions(+), 4 deletions(-)

diff --git a/Examples/app/Package.swift b/Examples/app/Package.swift
new file mode 100644
index 0000000..8afa325
--- /dev/null
+++ b/Examples/app/Package.swift
@@ -0,0 +1,37 @@
+// swift-tools-version: 6.0
+//
+// 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.
+//
+
+import PackageDescription
+
+let package = Package(
+  name: "SparkConnectSwiftApp",
+  platforms: [
+    .macOS(.v15)
+  ],
+  dependencies: [
+    .package(url: "https://github.com/apache/spark-connect-swift.git";, branch: 
"v0.1.0")
+  ],
+  targets: [
+    .executableTarget(
+      name: "SparkConnectSwiftApp",
+      dependencies: [.product(name: "SparkConnect", package: 
"spark-connect-swift")]
+    )
+  ]
+)
diff --git a/Examples/app/README.md b/Examples/app/README.md
new file mode 100644
index 0000000..285a0d3
--- /dev/null
+++ b/Examples/app/README.md
@@ -0,0 +1,33 @@
+# A Swift Application with Apache Spark Connect Swift Client
+
+This is an example Swift application to show how to use Apache Spark Connect 
Swift Client library.
+
+## How to run
+
+Run this Swift application.
+
+```
+$ swift run
+...
+Connected to Apache Spark 4.0.0 Server
+EXECUTE: DROP TABLE IF EXISTS t
+EXECUTE: CREATE TABLE IF NOT EXISTS t(a INT) USING ORC
+EXECUTE: INSERT INTO t VALUES (1), (2), (3)
+SELECT * FROM t
++---+
+| a |
++---+
+| 2 |
+| 1 |
+| 3 |
++---+
++----+
+| id |
++----+
+| 2  |
+| 6  |
+| 0  |
+| 8  |
+| 4  |
++----+
+```
diff --git a/Examples/app/Sources/main.swift b/Examples/app/Sources/main.swift
new file mode 100644
index 0000000..c9ae2e2
--- /dev/null
+++ b/Examples/app/Sources/main.swift
@@ -0,0 +1,41 @@
+//
+// 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.
+//
+
+import SparkConnect
+
+let spark = try await SparkSession.builder.getOrCreate()
+print("Connected to Apache Spark \(await spark.version) Server")
+
+let statements = [
+  "DROP TABLE IF EXISTS t",
+  "CREATE TABLE IF NOT EXISTS t(a INT) USING ORC",
+  "INSERT INTO t VALUES (1), (2), (3)",
+]
+
+for s in statements {
+  print("EXECUTE: \(s)")
+  _ = try await spark.sql(s).count()
+}
+print("SELECT * FROM t")
+try await spark.sql("SELECT * FROM t").cache().show()
+
+try await spark.range(10).filter("id % 2 == 
0").write.mode("overwrite").orc("/tmp/orc")
+try await spark.read.orc("/tmp/orc").show()
+
+await spark.stop()
diff --git a/Examples/web/Package.swift b/Examples/web/Package.swift
new file mode 100644
index 0000000..7d793ab
--- /dev/null
+++ b/Examples/web/Package.swift
@@ -0,0 +1,52 @@
+// swift-tools-version:6.0
+//
+// 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.
+//
+import PackageDescription
+
+let package = Package(
+  name: "SparkConnectSwiftWebapp",
+  platforms: [
+    .macOS(.v15)
+  ],
+  dependencies: [
+    // 💧 A server-side Swift web framework.
+    .package(url: "https://github.com/vapor/vapor.git";, from: "4.110.1"),
+    // 🔵 Non-blocking, event-driven networking for Swift. Used for custom 
executors
+    .package(url: "https://github.com/apple/swift-nio.git";, from: "2.65.0"),
+    .package(url: "https://github.com/apache/spark-connect-swift.git";, branch: 
"v0.1.0"),
+  ],
+  targets: [
+    .executableTarget(
+      name: "SparkConnectSwiftWebapp",
+      dependencies: [
+        .product(name: "Vapor", package: "vapor"),
+        .product(name: "NIOCore", package: "swift-nio"),
+        .product(name: "NIOPosix", package: "swift-nio"),
+        .product(name: "SparkConnect", package: "spark-connect-swift"),
+      ],
+      swiftSettings: swiftSettings
+    )
+  ]
+)
+
+var swiftSettings: [SwiftSetting] {
+  [
+    .enableUpcomingFeature("ExistentialAny")
+  ]
+}
diff --git a/Examples/web/README.md b/Examples/web/README.md
new file mode 100644
index 0000000..3ae473e
--- /dev/null
+++ b/Examples/web/README.md
@@ -0,0 +1,89 @@
+# A Swift Application with Apache Spark Connect Swift Client
+
+This project is designed to illustrate a Swift-based HTTP WebServer with 
Apache Spark Connect.
+
+- https://swiftpackageindex.com/apache/spark-connect-swift
+- https://swiftpackageindex.com/vapor/vapor
+
+## Create a Swift project
+
+```
+brew install vapor
+vapor new spark-connect-swift-web -n
+```
+
+## Use `Apache Spark Connect Swift Client` package.
+
+```
+$ git diff HEAD
+diff --git a/Package.swift b/Package.swift
+index 477bcbd..3e7bb06 100644
+--- a/Package.swift
++++ b/Package.swift
+@@ -4,13 +4,14 @@ import PackageDescription
+ let package = Package(
+     name: "SparkConnectSwiftWebapp",
+     platforms: [
+-       .macOS(.v13)
++       .macOS(.v15)
+     ],
+     dependencies: [
+         // 💧 A server-side Swift web framework.
+         .package(url: "https://github.com/vapor/vapor.git";, from: "4.110.1"),
+         // 🔵 Non-blocking, event-driven networking for Swift. Used for custom 
executors
+         .package(url: "https://github.com/apple/swift-nio.git";, from: 
"2.65.0"),
++        .package(url: "https://github.com/apache/spark-connect-swift.git";, 
branch: "main"),
+     ],
+     targets: [
+         .executableTarget(
+@@ -19,6 +20,7 @@ let package = Package(
+                 .product(name: "Vapor", package: "vapor"),
+                 .product(name: "NIOCore", package: "swift-nio"),
+                 .product(name: "NIOPosix", package: "swift-nio"),
++                .product(name: "SparkConnect", package: 
"spark-connect-swift"),
+             ],
+             swiftSettings: swiftSettings
+         ),
+diff --git a/Sources/SparkConnectSwiftWebapp/routes.swift 
b/Sources/SparkConnectSwiftWebapp/routes.swift
+index 2edcc8f..22313c8 100644
+--- a/Sources/SparkConnectSwiftWebapp/routes.swift
++++ b/Sources/SparkConnectSwiftWebapp/routes.swift
+@@ -1,4 +1,5 @@
+ import Vapor
++import SparkConnect
+
+ func routes(_ app: Application) throws {
+     app.get { req async in
+@@ -6,6 +7,15 @@ func routes(_ app: Application) throws {
+     }
+
+     app.get("hello") { req async -> String in
+-        "Hello, world!"
++        return await Task {
++            do {
++                let spark = try await SparkSession.builder.getOrCreate()
++                let response = "Hi, this is powered by the Apache Spark 
\(await spark.version)."
++                await spark.stop()
++                return response
++            } catch {
++                return "Fail to connect: \(error)"
++            }
++        }.value
+     }
+ }
+```
+
+## Run this Swift application.
+
+```
+$ swift run
+```
+
+## Connect to the Swift Web Server to talk with `Apache Spark`.
+
+```
+$ curl http://127.0.0.1:8080/
+Welcome to the Swift world. Say hello!%
+$ curl http://127.0.0.1:8080/hello
+Hi, this is powered by the Apache Spark 4.0.0.%
+```
diff --git a/Examples/web/Sources/SparkConnectSwiftWeb/configure.swift 
b/Examples/web/Sources/SparkConnectSwiftWeb/configure.swift
new file mode 100644
index 0000000..cbc3edb
--- /dev/null
+++ b/Examples/web/Sources/SparkConnectSwiftWeb/configure.swift
@@ -0,0 +1,26 @@
+//
+// 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.
+//
+
+import Vapor
+
+// configures your application
+public func configure(_ app: Application) async throws {
+  // register routes
+  try routes(app)
+}
diff --git a/Examples/web/Sources/SparkConnectSwiftWeb/entrypoint.swift 
b/Examples/web/Sources/SparkConnectSwiftWeb/entrypoint.swift
new file mode 100644
index 0000000..0be116f
--- /dev/null
+++ b/Examples/web/Sources/SparkConnectSwiftWeb/entrypoint.swift
@@ -0,0 +1,50 @@
+//
+// 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.
+//
+
+import Logging
+import NIOCore
+import NIOPosix
+import Vapor
+
+@main
+enum Entrypoint {
+  static func main() async throws {
+    var env = try Environment.detect()
+    try LoggingSystem.bootstrap(from: &env)
+
+    let app = try await Application.make(env)
+
+    // This attempts to install NIO as the Swift Concurrency global executor.
+    // You can enable it if you'd like to reduce the amount of context 
switching between NIO and Swift Concurrency.
+    // Note: this has caused issues with some libraries that use `.wait()` and 
cleanly shutting down.
+    // If enabled, you should be careful about calling async functions before 
this point as it can cause assertion failures.
+    // let executorTakeoverSuccess = 
NIOSingletons.unsafeTryInstallSingletonPosixEventLoopGroupAsConcurrencyGlobalExecutor()
+    // app.logger.debug("Tried to install SwiftNIO's EventLoopGroup as Swift's 
global concurrency executor", metadata: ["success": 
.stringConvertible(executorTakeoverSuccess)])
+
+    do {
+      try await configure(app)
+      try await app.execute()
+    } catch {
+      app.logger.report(error: error)
+      try? await app.asyncShutdown()
+      throw error
+    }
+    try await app.asyncShutdown()
+  }
+}
diff --git a/Examples/web/Sources/SparkConnectSwiftWeb/routes.swift 
b/Examples/web/Sources/SparkConnectSwiftWeb/routes.swift
new file mode 100644
index 0000000..c6a1d91
--- /dev/null
+++ b/Examples/web/Sources/SparkConnectSwiftWeb/routes.swift
@@ -0,0 +1,40 @@
+//
+// 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.
+//
+
+import SparkConnect
+import Vapor
+
+func routes(_ app: Application) throws {
+  app.get { req async in
+    "Welcome to the Swift world. Say hello!"
+  }
+
+  app.get("hello") { req async -> String in
+    return await Task {
+      do {
+        let spark = try await SparkSession.builder.getOrCreate()
+        let response = "Hi, this is powered by the Apache Spark \(await 
spark.version)."
+        await spark.stop()
+        return response
+      } catch {
+        return "Fail to connect: \(error)"
+      }
+    }.value
+  }
+}
diff --git a/README.md b/README.md
index eaf7148..395a6a0 100644
--- a/README.md
+++ b/README.md
@@ -108,10 +108,7 @@ SELECT * FROM t
 +----+
 ```
 
-You can find this command line example and additional `Swift Web Server` 
example in the following repositories.
-
-- <https://github.com/dongjoon-hyun/spark-connect-swift-app>
-- <https://github.com/dongjoon-hyun/spark-connect-swift-web>
+You can find more complete examples including Web Server application in the 
`Examples` directory.
 
 ## How to use `Spark SQL REPL` via `Spark Connect for Swift`
 


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to