stitchdb 1.0.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,55 @@
1
+ Metadata-Version: 2.4
2
+ Name: stitchdb
3
+ Version: 1.0.0
4
+ Summary: StitchDB database backend for Django
5
+ Home-page: https://github.com/stitchdb/django
6
+ Author: StitchDB
7
+ Author-email: support@stitchdb.com
8
+ License: MIT
9
+ Classifier: Framework :: Django
10
+ Classifier: Framework :: Django :: 3.2
11
+ Classifier: Framework :: Django :: 4.0
12
+ Classifier: Framework :: Django :: 4.1
13
+ Classifier: Framework :: Django :: 4.2
14
+ Classifier: Framework :: Django :: 5.0
15
+ Classifier: Framework :: Django :: 5.1
16
+ Classifier: Programming Language :: Python :: 3
17
+ Classifier: License :: OSI Approved :: MIT License
18
+ Requires-Python: >=3.7
19
+ Description-Content-Type: text/markdown
20
+ Requires-Dist: django>=3.2
21
+ Requires-Dist: requests>=2.25.0
22
+ Dynamic: author
23
+ Dynamic: author-email
24
+ Dynamic: classifier
25
+ Dynamic: description
26
+ Dynamic: description-content-type
27
+ Dynamic: home-page
28
+ Dynamic: license
29
+ Dynamic: requires-dist
30
+ Dynamic: requires-python
31
+ Dynamic: summary
32
+
33
+ # StitchDB for Django
34
+
35
+ ## Install
36
+
37
+ ```bash
38
+ pip install stitchdb
39
+ ```
40
+
41
+ ## Configure
42
+
43
+ In `settings.py`:
44
+
45
+ ```python
46
+ DATABASES = {
47
+ 'default': {
48
+ 'ENGINE': 'stitchdb_django',
49
+ 'URL': os.environ.get('STITCHDB_URL', 'https://db.stitchdb.com'),
50
+ 'API_KEY': os.environ.get('STITCHDB_API_KEY', ''),
51
+ }
52
+ }
53
+ ```
54
+
55
+ No other setup needed. Run `python manage.py migrate` and use Django ORM as usual.
@@ -0,0 +1,23 @@
1
+ # StitchDB for Django
2
+
3
+ ## Install
4
+
5
+ ```bash
6
+ pip install stitchdb
7
+ ```
8
+
9
+ ## Configure
10
+
11
+ In `settings.py`:
12
+
13
+ ```python
14
+ DATABASES = {
15
+ 'default': {
16
+ 'ENGINE': 'stitchdb_django',
17
+ 'URL': os.environ.get('STITCHDB_URL', 'https://db.stitchdb.com'),
18
+ 'API_KEY': os.environ.get('STITCHDB_API_KEY', ''),
19
+ }
20
+ }
21
+ ```
22
+
23
+ No other setup needed. Run `python manage.py migrate` and use Django ORM as usual.
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,30 @@
1
+ from setuptools import setup, find_packages
2
+
3
+ setup(
4
+ name="stitchdb",
5
+ version="1.0.0",
6
+ description="StitchDB database backend for Django",
7
+ long_description=open("README.md").read(),
8
+ long_description_content_type="text/markdown",
9
+ author="StitchDB",
10
+ author_email="support@stitchdb.com",
11
+ url="https://github.com/stitchdb/django",
12
+ packages=find_packages(),
13
+ install_requires=[
14
+ "django>=3.2",
15
+ "requests>=2.25.0",
16
+ ],
17
+ python_requires=">=3.7",
18
+ license="MIT",
19
+ classifiers=[
20
+ "Framework :: Django",
21
+ "Framework :: Django :: 3.2",
22
+ "Framework :: Django :: 4.0",
23
+ "Framework :: Django :: 4.1",
24
+ "Framework :: Django :: 4.2",
25
+ "Framework :: Django :: 5.0",
26
+ "Framework :: Django :: 5.1",
27
+ "Programming Language :: Python :: 3",
28
+ "License :: OSI Approved :: MIT License",
29
+ ],
30
+ )
@@ -0,0 +1,55 @@
1
+ Metadata-Version: 2.4
2
+ Name: stitchdb
3
+ Version: 1.0.0
4
+ Summary: StitchDB database backend for Django
5
+ Home-page: https://github.com/stitchdb/django
6
+ Author: StitchDB
7
+ Author-email: support@stitchdb.com
8
+ License: MIT
9
+ Classifier: Framework :: Django
10
+ Classifier: Framework :: Django :: 3.2
11
+ Classifier: Framework :: Django :: 4.0
12
+ Classifier: Framework :: Django :: 4.1
13
+ Classifier: Framework :: Django :: 4.2
14
+ Classifier: Framework :: Django :: 5.0
15
+ Classifier: Framework :: Django :: 5.1
16
+ Classifier: Programming Language :: Python :: 3
17
+ Classifier: License :: OSI Approved :: MIT License
18
+ Requires-Python: >=3.7
19
+ Description-Content-Type: text/markdown
20
+ Requires-Dist: django>=3.2
21
+ Requires-Dist: requests>=2.25.0
22
+ Dynamic: author
23
+ Dynamic: author-email
24
+ Dynamic: classifier
25
+ Dynamic: description
26
+ Dynamic: description-content-type
27
+ Dynamic: home-page
28
+ Dynamic: license
29
+ Dynamic: requires-dist
30
+ Dynamic: requires-python
31
+ Dynamic: summary
32
+
33
+ # StitchDB for Django
34
+
35
+ ## Install
36
+
37
+ ```bash
38
+ pip install stitchdb
39
+ ```
40
+
41
+ ## Configure
42
+
43
+ In `settings.py`:
44
+
45
+ ```python
46
+ DATABASES = {
47
+ 'default': {
48
+ 'ENGINE': 'stitchdb_django',
49
+ 'URL': os.environ.get('STITCHDB_URL', 'https://db.stitchdb.com'),
50
+ 'API_KEY': os.environ.get('STITCHDB_API_KEY', ''),
51
+ }
52
+ }
53
+ ```
54
+
55
+ No other setup needed. Run `python manage.py migrate` and use Django ORM as usual.
@@ -0,0 +1,15 @@
1
+ README.md
2
+ setup.py
3
+ stitchdb.egg-info/PKG-INFO
4
+ stitchdb.egg-info/SOURCES.txt
5
+ stitchdb.egg-info/dependency_links.txt
6
+ stitchdb.egg-info/requires.txt
7
+ stitchdb.egg-info/top_level.txt
8
+ stitchdb_django/__init__.py
9
+ stitchdb_django/base.py
10
+ stitchdb_django/client.py
11
+ stitchdb_django/creation.py
12
+ stitchdb_django/features.py
13
+ stitchdb_django/introspection.py
14
+ stitchdb_django/operations.py
15
+ stitchdb_django/schema.py
@@ -0,0 +1,2 @@
1
+ django>=3.2
2
+ requests>=2.25.0
@@ -0,0 +1 @@
1
+ stitchdb_django
@@ -0,0 +1 @@
1
+ """StitchDB database backend for Django."""
@@ -0,0 +1,156 @@
1
+ """
2
+ StitchDB database backend for Django.
3
+ Wraps the StitchDB HTTP API behind Django's database backend interface.
4
+ Uses SQLite-compatible SQL since StitchDB uses SQLite under the hood.
5
+ """
6
+
7
+ from django.db.backends.sqlite3.base import DatabaseWrapper as SQLiteDatabaseWrapper
8
+ from django.db.backends.sqlite3.base import Database
9
+ from .client import StitchDBClient
10
+ from .creation import DatabaseCreation
11
+ from .features import DatabaseFeatures
12
+ from .introspection import DatabaseIntrospection
13
+ from .operations import DatabaseOperations
14
+ from .schema import DatabaseSchemaEditor
15
+
16
+ import sqlite3
17
+ import json
18
+
19
+
20
+ class StitchDBCursorWrapper:
21
+ """A cursor that sends queries to StitchDB's HTTP API."""
22
+
23
+ def __init__(self, client):
24
+ self.client = client
25
+ self.description = None
26
+ self._results = []
27
+ self._rowcount = -1
28
+ self.lastrowid = None
29
+ self.arraysize = 1
30
+
31
+ @property
32
+ def rowcount(self):
33
+ return self._rowcount
34
+
35
+ def execute(self, sql, params=None):
36
+ sql = str(sql).strip()
37
+ if not sql:
38
+ return
39
+
40
+ # Convert Django's %s placeholders to ? for SQLite
41
+ if params:
42
+ sql = sql.replace("%s", "?")
43
+ params = list(params)
44
+ else:
45
+ params = None
46
+
47
+ try:
48
+ result = self.client.query(sql, params)
49
+ results = result.get("results", [])
50
+ meta = result.get("meta", {})
51
+
52
+ self.lastrowid = meta.get("last_row_id")
53
+ self._rowcount = meta.get("rows_written", len(results))
54
+
55
+ if results and len(results) > 0:
56
+ columns = list(results[0].keys())
57
+ self.description = [
58
+ (col, None, None, None, None, None, None) for col in columns
59
+ ]
60
+ self._results = [tuple(row.get(col) for col in columns) for row in results]
61
+ else:
62
+ self.description = None
63
+ self._results = []
64
+ except Exception as e:
65
+ raise Exception(str(e))
66
+
67
+ def executemany(self, sql, param_list):
68
+ for params in param_list:
69
+ self.execute(sql, params)
70
+
71
+ def fetchone(self):
72
+ if self._results:
73
+ return self._results.pop(0)
74
+ return None
75
+
76
+ def fetchmany(self, size=None):
77
+ if size is None:
78
+ size = self.arraysize
79
+ results = self._results[:size]
80
+ self._results = self._results[size:]
81
+ return results
82
+
83
+ def fetchall(self):
84
+ results = self._results
85
+ self._results = []
86
+ return results
87
+
88
+ def close(self):
89
+ pass
90
+
91
+ def __iter__(self):
92
+ return iter(self._results)
93
+
94
+
95
+ class DatabaseWrapper(SQLiteDatabaseWrapper):
96
+ vendor = "stitchdb"
97
+ display_name = "StitchDB"
98
+
99
+ # Use SQLite data types
100
+ data_types = SQLiteDatabaseWrapper.data_types
101
+
102
+ SchemaEditorClass = DatabaseSchemaEditor
103
+
104
+ def __init__(self, *args, **kwargs):
105
+ super().__init__(*args, **kwargs)
106
+ self.features = DatabaseFeatures(self)
107
+ self.ops = DatabaseOperations(self)
108
+ self.creation = DatabaseCreation(self)
109
+ self.introspection = DatabaseIntrospection(self)
110
+ self._stitchdb_client = None
111
+
112
+ def get_stitchdb_client(self):
113
+ if self._stitchdb_client is None:
114
+ url = self.settings_dict.get("URL", "https://db.stitchdb.com")
115
+ api_key = self.settings_dict.get("API_KEY", "")
116
+ self._stitchdb_client = StitchDBClient(url, api_key)
117
+ return self._stitchdb_client
118
+
119
+ def get_connection_params(self):
120
+ return {"database": ":memory:"}
121
+
122
+ def get_new_connection(self, conn_params):
123
+ # We need a real SQLite connection for Django's internals
124
+ # (schema introspection, etc.) but all actual queries go through HTTP
125
+ conn = Database.connect(":memory:")
126
+ return conn
127
+
128
+ def create_cursor(self, name=None):
129
+ return StitchDBCursorWrapper(self.get_stitchdb_client())
130
+
131
+ def _cursor(self):
132
+ return self.create_cursor()
133
+
134
+ def is_usable(self):
135
+ return True
136
+
137
+ def _set_autocommit(self, autocommit):
138
+ pass
139
+
140
+ def _start_transaction_under_autocommit(self):
141
+ pass
142
+
143
+ def _savepoint(self, sid):
144
+ pass
145
+
146
+ def _savepoint_rollback(self, sid):
147
+ pass
148
+
149
+ def _savepoint_commit(self, sid):
150
+ pass
151
+
152
+ def _commit(self):
153
+ pass
154
+
155
+ def _rollback(self):
156
+ pass
@@ -0,0 +1,27 @@
1
+ import requests
2
+
3
+
4
+ class StitchDBClient:
5
+ def __init__(self, url, api_key):
6
+ self.url = url.rstrip("/")
7
+ self.api_key = api_key
8
+ self.session = requests.Session()
9
+ self.session.headers.update(
10
+ {
11
+ "Authorization": f"Bearer {self.api_key}",
12
+ "Content-Type": "application/json",
13
+ }
14
+ )
15
+
16
+ def query(self, sql, params=None):
17
+ body = {"sql": sql}
18
+ if params:
19
+ body["params"] = list(params)
20
+ resp = self.session.post(f"{self.url}/v1/query", json=body)
21
+ data = resp.json()
22
+ if "error" in data:
23
+ raise Exception(f"StitchDB: {data['error']}")
24
+ return data
25
+
26
+ def execute(self, sql, params=None):
27
+ return self.query(sql, params)
@@ -0,0 +1,9 @@
1
+ from django.db.backends.sqlite3.creation import DatabaseCreation as SQLiteCreation
2
+
3
+
4
+ class DatabaseCreation(SQLiteCreation):
5
+ def create_test_db(self, *args, **kwargs):
6
+ pass
7
+
8
+ def destroy_test_db(self, *args, **kwargs):
9
+ pass
@@ -0,0 +1,8 @@
1
+ from django.db.backends.sqlite3.features import DatabaseFeatures as SQLiteFeatures
2
+
3
+
4
+ class DatabaseFeatures(SQLiteFeatures):
5
+ supports_transactions = False
6
+ supports_atomic_references_rename = False
7
+ can_clone_databases = False
8
+ supports_json_field = False
@@ -0,0 +1,5 @@
1
+ from django.db.backends.sqlite3.introspection import DatabaseIntrospection as SQLiteIntrospection
2
+
3
+
4
+ class DatabaseIntrospection(SQLiteIntrospection):
5
+ pass
@@ -0,0 +1,5 @@
1
+ from django.db.backends.sqlite3.operations import DatabaseOperations as SQLiteOperations
2
+
3
+
4
+ class DatabaseOperations(SQLiteOperations):
5
+ pass
@@ -0,0 +1,5 @@
1
+ from django.db.backends.sqlite3.schema import DatabaseSchemaEditor as SQLiteSchemaEditor
2
+
3
+
4
+ class DatabaseSchemaEditor(SQLiteSchemaEditor):
5
+ pass