Skip to content

Commit 8ba32bd

Browse files
committed
Merge branch 'staging' into docs
2 parents dc2941e + 67f1983 commit 8ba32bd

File tree

16 files changed

+338
-124
lines changed

16 files changed

+338
-124
lines changed
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
name: Add Pull Requests to PR review project
2+
3+
on:
4+
pull_request:
5+
types:
6+
- opened
7+
8+
jobs:
9+
add-to-project:
10+
name: Add issue to project
11+
runs-on: ubuntu-latest
12+
steps:
13+
- uses: actions/add-to-project@v0.5.0
14+
with:
15+
project-url: https://github.com/orgs/mindsdb/projects/65
16+
github-token: ${{ secrets.ADD_TO_PROJECT_PAT }}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
name: Add issue to roadmap project
2+
on:
3+
issues:
4+
types:
5+
- opened
6+
jobs:
7+
add-to-project:
8+
name: Add issue to roadmap project
9+
runs-on: ubuntu-latest
10+
steps:
11+
- uses: actions/add-to-project@v0.4.0
12+
with:
13+
project-url: https://github.com/orgs/mindsdb/projects/53
14+
github-token: ${{ secrets.ADD_TO_PROJECT_PAT }}

.github/workflows/mindsdb_python_sdk.yml

Lines changed: 3 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
1-
name: MindsDB Native workflow
1+
name: PR workflow
22

33
on:
4-
push:
54
pull_request:
65
branches:
76
- stable
@@ -43,6 +42,8 @@ jobs:
4342
needs: test
4443
if: github.ref != 'refs/heads/stable'
4544
runs-on: ubuntu-latest
45+
permissions:
46+
pull-requests: write
4647
steps:
4748
- uses: actions/checkout@v3
4849
- name: Set up Python 3.8
@@ -65,25 +66,3 @@ jobs:
6566
with:
6667
pytest-coverage-path: ./pytest-coverage.txt
6768
junitxml-path: ./pytest.xml
68-
69-
deploy:
70-
runs-on: ubuntu-latest
71-
needs: test
72-
if: github.ref == 'refs/heads/stable'
73-
steps:
74-
- uses: actions/checkout@v2
75-
- name: Set up Python
76-
uses: actions/setup-python@v2
77-
with:
78-
python-version: '3.7'
79-
- name: Install dependencies
80-
run: |
81-
python -m pip install --upgrade pip==20.2.4
82-
pip install setuptools wheel twine
83-
- name: Build and publish
84-
env:
85-
TWINE_USERNAME: __token__
86-
TWINE_PASSWORD: ${{ secrets.PYPI_PASSWORD }}
87-
run: |
88-
python setup.py sdist
89-
twine upload dist/*

.github/workflows/release.yml

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
name: Release
2+
3+
on:
4+
push:
5+
branches:
6+
- stable
7+
8+
jobs:
9+
test:
10+
runs-on: ${{ matrix.os }}
11+
strategy:
12+
matrix:
13+
os: [ubuntu-latest]
14+
python-version: [3.7,3.8,3.9]
15+
steps:
16+
- uses: actions/checkout@v2
17+
- name: Set up Python ${{ matrix.python-version }}
18+
uses: actions/setup-python@v2
19+
with:
20+
python-version: ${{ matrix.python-version }}
21+
- name: Install dependencies
22+
run: |
23+
python -m pip install --upgrade pip==22.0.4
24+
pip install -r requirements.txt
25+
pip install --no-cache-dir .
26+
- name: Run tests
27+
run: |
28+
if [ "$RUNNER_OS" == "Linux" ]; then
29+
30+
env PYTHONPATH=./ pytest tests/
31+
32+
fi
33+
shell: bash
34+
env:
35+
CHECK_FOR_UPDATES: False
36+
DATABASE_CREDENTIALS_STRINGIFIED_JSON: ${{ secrets.DATABASE_CREDENTIALS }}
37+
CLOUD_TEST_EMAIL: ${{ secrets.CLOUD_TEST_EMAIL }}
38+
CLOUD_TEST_PASSWORD: ${{ secrets.CLOUD_TEST_PASSWORD }}
39+
40+
41+
deploy:
42+
runs-on: ubuntu-latest
43+
needs: test
44+
if: github.ref == 'refs/heads/stable'
45+
steps:
46+
- uses: actions/checkout@v2
47+
- name: Set up Python
48+
uses: actions/setup-python@v2
49+
with:
50+
python-version: '3.7'
51+
- name: Install dependencies
52+
run: |
53+
python -m pip install --upgrade pip==20.2.4
54+
pip install setuptools wheel twine
55+
- name: Build and publish
56+
env:
57+
TWINE_USERNAME: __token__
58+
TWINE_PASSWORD: ${{ secrets.PYPI_PASSWORD }}
59+
run: |
60+
python setup.py sdist
61+
twine upload dist/*

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ https://github.com/mindsdb/mindsdb_python_sdk/tree/staging/examples
107107

108108
## API Documentation
109109

110-
The API documentation for the MindsDB SDK can be found at https://mindsdb.github.io/mindsdb_python_sdk/. You can generate the API documentation locally by following these steps:
110+
The API documentation for the MindsDB SDK can be found at https://mindsdb.github.io/mindsdb_python_sdk/.
111111

112112
### Generating API docs locally:
113113

examples/working_with_tables.py

Lines changed: 34 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,21 +3,44 @@
33

44
con = mindsdb_sdk.connect()
55

6-
# get user's database (connected to mindsdb as rental_db)
7-
db = con.databases.rental_db
6+
# connect to mindsdb example database
7+
example_db = con.databases.create(
8+
'example_db',
9+
engine='postgres',
10+
connection_args={
11+
"user": "demo_user",
12+
"password": "demo_password",
13+
"host": "3.220.66.106",
14+
"port": "5432",
15+
"database": "demo"
16+
}
17+
)
818

9-
# get table
10-
table1 = db.tables.house_sales
19+
# connect to the empty user database
20+
my_db = con.databases.create(
21+
'my_db',
22+
engine='postgres',
23+
connection_args={
24+
"user": "postgres",
25+
"host": "localhost",
26+
"port": "5432",
27+
"database": "my_database"
28+
}
29+
)
1130

31+
# get home_rentals table
32+
table1 = example_db.tables.get('demo_data.home_rentals')
1233

1334
# ---- create new table ----
1435

15-
# copy create table house_sales and fill it with rows with type=house
16-
table2 = db.tables.create('house_sales2', table1.filter(type='house'))
36+
# create table home_rentals in user db and fill it with rows with location=great
37+
table2 = my_db.tables.create('home_rentals', table1.filter(location='great'))
38+
1739

1840
# create table from csv file
41+
1942
df = pd.read_csv('my_data.csv')
20-
table3 = db.tables.create('my_table', df)
43+
table3 = my_db.tables.create('my_table', df)
2144

2245

2346
# ---- insert into table ----
@@ -28,16 +51,16 @@
2851

2952
# ---- update data in table ----
3053

31-
# get all rows with type=house from table1 and update values in table2 using key ('saledate', 'type', 'bedrooms')
54+
# get all rows with number_of_rooms=1 from table1 and update values in table2 using key ('location', 'neighborhood')
3255
table2.update(
33-
table1.filter(type='house'),
34-
on=['saledate', 'type', 'bedrooms']
56+
table1.filter(number_of_rooms=1),
57+
on=['location', 'neighborhood']
3558
)
3659

3760

3861
# ---- delete rows from table ----
3962

4063
# delete all rows where bedrooms=2
41-
table2.delete(bedrooms=2)
64+
table2.delete(number_of_rooms=1)
4265

4366

mindsdb_sdk/__about__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
__title__ = 'mindsdb_sdk'
22
__package_name__ = 'mindsdb_sdk'
3-
__version__ = '2.0.0'
3+
__version__ = '2.1.0'
44
__description__ = "MindsDB Python SDK, provides an SDK to use a remote mindsdb instance"
55
__email__ = "jorge@mindsdb.com"
66
__author__ = 'MindsDB Inc'

mindsdb_sdk/connectors/rest_api.py

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,7 @@ def upload_file(self, name: str, df: pd.DataFrame):
124124

125125
# convert to file
126126
fd = io.BytesIO()
127-
df.to_csv(fd)
127+
df.to_csv(fd, index=False)
128128
fd.seek(0)
129129

130130
url = self.url + f'/api/files/{name}'
@@ -139,4 +139,24 @@ def upload_file(self, name: str, df: pd.DataFrame):
139139
'file': fd,
140140
}
141141
)
142-
_raise_for_status(r)
142+
_raise_for_status(r)
143+
144+
@_try_relogin
145+
def upload_byom(self, name: str, code: str, requirements: str):
146+
147+
url = self.url + f'/api/handlers/byom/{name}'
148+
r = self.session.put(
149+
url,
150+
files={
151+
'code': code,
152+
'modules': requirements,
153+
}
154+
)
155+
_raise_for_status(r)
156+
157+
def status(self) -> dict:
158+
159+
r = self.session.get(self.url + f'/api/status')
160+
_raise_for_status(r)
161+
162+
return r.json()

mindsdb_sdk/databases.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
from typing import List
1+
from typing import List, Union
22

33
from mindsdb_sql.parser.dialects.mindsdb import CreateDatabase
44
from mindsdb_sql.parser.ast import DropDatabase, Identifier
@@ -7,6 +7,7 @@
77

88
from .query import Query
99
from .tables import Tables
10+
from .handlers import Handler
1011

1112

1213
class Database:
@@ -93,7 +94,7 @@ def list(self) -> List[Database]:
9394
"""
9495
return [Database(self, name) for name in self._list_databases()]
9596

96-
def create(self, name: str, engine: str, connection_args: dict) -> Database:
97+
def create(self, name: str, engine: Union[str, Handler], connection_args: dict) -> Database:
9798
"""
9899
Create new integration and return it
99100
@@ -102,6 +103,9 @@ def create(self, name: str, engine: str, connection_args: dict) -> Database:
102103
:param connection_args: {"key": "value"} object with the connection parameters specific for each engine
103104
:return: created Database object
104105
"""
106+
if isinstance(engine, Handler):
107+
engine = engine.name
108+
105109
ast_query = CreateDatabase(
106110
name=Identifier(name),
107111
engine=engine,

mindsdb_sdk/ml_engines.py

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,16 @@ class MLEngines(CollectionBase):
4545
4646
>>> con.ml_engines.drop('openai1')
4747
48+
Upload BYOM model. After uploading a new ml engin will be availbe to create new model from it.
49+
50+
>>> model_code = open('/path/to/model/code').read()
51+
>>> model_requirements = open('/path/to/model/requirements').read()
52+
>>> ml_engine = con.ml_engines.create_byom(
53+
... 'my_byom_engine',
54+
... code=model_code,
55+
... requirements=model_requirements
56+
...)
57+
4858
"""
4959

5060
def __init__(self, api):
@@ -101,6 +111,25 @@ def create(self, name: str, handler: Union[str, Handler], connection_data: dict
101111

102112
return MLEngine(name, handler, connection_data)
103113

114+
def create_byom(self, name: str, code: str, requirements: Union[str, List[str]] = None):
115+
"""
116+
Create new BYOM ML engine and return it
117+
118+
:param code: model python code in string
119+
:param requirements: requirements for model. Optional if there is no special requirements.
120+
It can be content of 'requirement.txt' file or list of strings (item for every requirement).
121+
:return: created BYOM ml engine object
122+
"""
123+
124+
if requirements is None:
125+
requirements = ''
126+
elif isinstance(requirements, list):
127+
requirements = '\n'.join(requirements)
128+
129+
self.api.upload_byom(name, code, requirements)
130+
131+
return MLEngine(name, 'byom', {})
132+
104133
def drop(self, name: str):
105134
"""
106135
Drop ml engine by name

0 commit comments

Comments
 (0)