Skip to content

Commit

Permalink
Add setup.py
Browse files Browse the repository at this point in the history
Update environment.yml to create the editable install

Sproc now returns a table
  • Loading branch information
sfc-gh-jfreeberg committed May 13, 2023
1 parent 8639aa6 commit ae690f7
Show file tree
Hide file tree
Showing 10 changed files with 56 additions and 55 deletions.
28 changes: 13 additions & 15 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,22 +31,22 @@ using the System Properties menu (on Windows).

### Install dependencies

Set up a virtual environment using [Anaconda](https://conda.io/projects/conda/en/latest/user-guide/tasks/manage-environments.html#creating-an-environment-with-commands) or [virtualenv](https://docs.python.org/3/library/venv.html).

#### Anaconda
Create and activate a conda environment using [Anaconda](https://conda.io/projects/conda/en/latest/user-guide/tasks/manage-environments.html#creating-an-environment-with-commands):

```bash
conda env create -f environment.yml
conda env create --file environment.yml
conda activate snowpark
```

#### Virtualenv
### Configure IDE

```bash
python3 -m venv venv
source venv/bin/activate
pip install -r requirements.txt
```
#### VS Code

Press `Ctrl`+`Shift`+`P` to open the command palette, then select **Python: Select Interpreter** and select the **snowpark** interpeter under the **Conda** list.

#### PyCharm

Go to **File** > **Settings** > **Project** > **Python Interpreter** and select the snowpark interpreter.

## Prereqs

Expand All @@ -60,9 +60,8 @@ To develop your applications locally, you will need

Once you've set your credentials and installed the packages, you can test your connection to Snowflake by executing the stored procedure in [`app.py`](src/procs/app.py):

```
cd src
python procs/app.py
```bash
python src/procs/app.py
```

You should see the following output:
Expand All @@ -80,8 +79,7 @@ You should see the following output:

You can run the test suite locally from the project root:

```
pip install -r requirements-test.txt
```bash
python -m pytest
```

Expand Down
6 changes: 2 additions & 4 deletions environment.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,6 @@ channels:
dependencies:
- python=3.8
- pip
- snowflake-snowpark-python
- toml
- tomli
- pip:
- "-r requirements-test.txt"
- "-r requirements.txt"
- "--editable ."
2 changes: 0 additions & 2 deletions requirements-test.txt

This file was deleted.

2 changes: 2 additions & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
snowflake-snowpark-python
tomli
toml
pytest
snowflake-vcrpy @ git+https://github.com/Snowflake-Labs/[email protected]
2 changes: 1 addition & 1 deletion resources.sql
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ CREATE STAGE IF NOT EXISTS artifacts;
PUT file://&artifact_name @artifacts AUTO_COMPRESS=FALSE OVERWRITE=TRUE;

CREATE OR REPLACE PROCEDURE HELLO_WORLD_PROC()
RETURNS integer
RETURNS TABLE(hello_world string)
LANGUAGE PYTHON
RUNTIME_VERSION = 3.8
IMPORTS = ('@artifacts/&artifact_name')
Expand Down
12 changes: 12 additions & 0 deletions setup.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
"""
Run `conda env create --file environment.yaml` to create an editable
install of this project
"""

from setuptools import setup, find_packages

setup(
name="Example Snowpark Python project",
version="0.1.0",
packages=find_packages()
)
Empty file added src/__init__.py
Empty file.
29 changes: 10 additions & 19 deletions src/procs/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
from snowflake.snowpark.types import StringType


def run(snowpark_session: Session) -> int:
def run(snowpark_session: Session) -> DataFrame:
"""
A sample stored procedure which creates a small DataFrame, prints it to the
console, and returns the number of rows in the table.
Expand All @@ -17,41 +17,32 @@ def run(snowpark_session: Session) -> int:
# Register UDF
from src.udf.functions import combine

snowpark_session.add_import(
path="../src/udf/functions.py", import_path="src.udf.functions"
)
combine = snowpark_session.udf.register(
combine, StringType(), input_types=[StringType(), StringType()]
)

schema = ["col_1", "col_2"]

data = [
("Welcome to ", "Snowflake!"),
("Learn more: ", "https://www.snowflake.com/snowpark/"),
]

df: DataFrame = snowpark_session.create_dataframe(data, schema)
df = snowpark_session.create_dataframe(data, schema)

df2 = df.select(combine(col("col_1"), col("col_2")).as_("Hello world")).sort(
"Hello world", ascending=False
df2 = df.select(combine(col("col_1"), col("col_2")).as_("hello_world")).sort(
"hello_world", ascending=False
)

df2.show()
return df2.count()
return df2


if __name__ == "__main__":
# This entrypoint is used for local development.

import sys

sys.path.insert(0, "..") # Necessary to import from udf and util directories

from src.util.local import get_env_var_config

print("Creating session...")
session = Session.builder.configs(get_env_var_config()).create()

print("Running stored proc...")
run(session)
print("Running stored procedure...")
result = run(session)

print("Stored procedure complete:")
result.show()
2 changes: 2 additions & 0 deletions src/udf/functions.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@
This module contains the UDFs for the project.
"""

from snowflake.snowpark.functions import udf

@udf(is_permanent=False)
def combine(string_a: str, string_b: str) -> str:
"""
A sample UDF implementation
Expand Down
28 changes: 14 additions & 14 deletions test/procs/test_app.py
Original file line number Diff line number Diff line change
@@ -1,24 +1,24 @@
import os

import pytest
from snowflake.snowpark.session import Session
from snowflake.snowpark.types import StringType
from src.util.local import get_env_var_config
from src.procs.app import run


@pytest.fixture(autouse=True)
def set_working_directory():
# Sets the working directory to sources root so relative imports resolve properly
os.chdir("src")


@pytest.fixture
def local_session():
def session():
return Session.builder.configs(get_env_var_config()).create()


@pytest.mark.snowflake_vcr
def test_app_dim(local_session):
expected_n_rows = 2
actual_n_rows = run(local_session)
assert expected_n_rows == actual_n_rows

def test_app_dim(session: Session):
expected = session.create_dataframe(
[["Welcome to Snowflake!"], ["Learn more: https://www.snowflake.com/snowpark/"]],
["hello_world"])
actual = run(session)
assert expected.collect() == actual.collect()

# Alertnate impl:
# expected = [Row("Welcome to Snowflake!"), Row("Learn more: https://www.snowflake.com/snowpark/")]
# actual = run(session)
# assert expected.select("hello_world").collect() == actual

0 comments on commit ae690f7

Please sign in to comment.