Skip to content

Commit 5c2cd50

Browse files
Support Executing SQL (#6)
* Add fixtures for pg connection * Test that we return a postgres client * Support instantiating postgres connection * Install psycopg2 * Ignore local configs * Properly configure bearer token
1 parent 7fe7bc2 commit 5c2cd50

File tree

8 files changed

+140
-17
lines changed

8 files changed

+140
-17
lines changed

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
# local configs
2+
env.*.local
3+
14
# Byte-compiled / optimized / DLL files
25
__pycache__/
36
*.py[cod]

Pipfile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ name = "pypi"
55

66
[packages]
77
slack-sdk = "*"
8+
psycopg2 = "*"
89

910
[dev-packages]
1011
pytest = "*"

Pipfile.lock

Lines changed: 31 additions & 16 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/wayscript/integrations/sql/__init__.py

Whitespace-only changes.
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
import json
2+
3+
import psycopg2
4+
5+
from wayscript import utils
6+
from wayscript.errors import MissingCredentialsError
7+
8+
9+
def get_connection_kwargs(_id: str) -> dict:
10+
"""
11+
Return postgres connection kwargs
12+
13+
If you want to instantiate your own client, use this method.
14+
"""
15+
wayscript_client = utils.WayScriptClient()
16+
response = wayscript_client.get_workspace_integration_detail(_id)
17+
response.raise_for_status()
18+
workspace_integration_data = response.json()
19+
credentials_str = workspace_integration_data.get("credentials")
20+
credentials = {}
21+
22+
try:
23+
credentials = json.loads(credentials_str)
24+
except json.decoder.JSONDecodeError:
25+
credentials = {}
26+
27+
kwargs = {
28+
"dbname": credentials.get("database_name"),
29+
"user": credentials.get("database_user"),
30+
"password": credentials.get("database_password"),
31+
"host": credentials.get("database_host"),
32+
"port": credentials.get("database_port", 5432),
33+
}
34+
35+
if not credentials or not all(v for v in kwargs.values()):
36+
raise MissingCredentialsError(f"Missing credentials for workspace_integration={_id}")
37+
38+
return kwargs
39+
40+
41+
def get_client_for_workspace_integration(_id: str):
42+
"""Instantiate connection from workspace integration kwargs"""
43+
kwargs = get_connection_kwargs(_id)
44+
return psycopg2.connect(**kwargs)

src/wayscript/utils.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,9 @@ class WayScriptClient:
2323
def __init__(self, *args, **kwargs):
2424
"""Init a wayscript client"""
2525
self.session = requests.Session()
26-
self.session.headers["authorization"] = get_process_execution_user_token()
26+
access_token = get_process_execution_user_token()
27+
self.session.headers["authorization"] = f"Bearer {access_token}"
28+
self.session.headers["content-type"] = "application/json"
2729

2830
def _get_url(self, subpath: str, route: str, template_args: dict=None):
2931
"""Generate an url"""

tests/conftest.py

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,3 +101,30 @@ def workspace_integrations_detail_response():
101101
})
102102
}
103103
return data
104+
105+
@pytest.fixture
106+
def workspace_integration_sql_credentials():
107+
"""Data for sql credentials"""
108+
data = {
109+
"database_name": "my_db",
110+
"database_user": "zach",
111+
"database_port": 15432,
112+
"database_password": "very-secret-password",
113+
"database_host": "host.docker.internal"
114+
}
115+
return data
116+
117+
118+
@pytest.fixture
119+
def workspace_integrations_detail_response_sql(workspace_integration_sql_credentials):
120+
"""
121+
Data from GET /workspaces-integrations/<id>
122+
123+
For type=sql
124+
"""
125+
data = {
126+
"id": WORKSPACE_INTEGRATION_ID,
127+
"type": "sql",
128+
"credentials": json.dumps(workspace_integration_sql_credentials),
129+
}
130+
return data
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
from unittest import mock
2+
3+
import psycopg2
4+
import responses
5+
6+
from wayscript.integrations.sql import postgres
7+
8+
9+
@responses.activate
10+
def test_get_postgres_client_for_workspace_integration(
11+
monkeypatch,
12+
patch_client_get_url,
13+
workspace_integration_sql_credentials,
14+
workspace_integrations_detail_response_sql,
15+
):
16+
"""Test getting postgres client kwargs"""
17+
connection = "my-connection"
18+
monkeypatch.setattr(psycopg2, "connect", mock.Mock(return_value=connection))
19+
20+
responses.add(
21+
responses.GET,
22+
patch_client_get_url,
23+
json=workspace_integrations_detail_response_sql,
24+
status=200,
25+
)
26+
27+
_id = workspace_integrations_detail_response_sql["id"]
28+
29+
assert connection == postgres.get_client_for_workspace_integration(_id)
30+
31+
psycopg2.connect.assert_called_with(dbname='my_db', user='zach', password='very-secret-password', host='host.docker.internal', port=15432)

0 commit comments

Comments
 (0)