pybasedb-json 0.3.0__tar.gz → 0.5.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.
- pybasedb_json-0.5.0/PKG-INFO +173 -0
- pybasedb_json-0.5.0/README.md +147 -0
- pybasedb_json-0.5.0/pybase/__init__.py +48 -0
- pybasedb_json-0.5.0/pybase/__main__.py +5 -0
- pybasedb_json-0.5.0/pybase/async_.py +66 -0
- {pybasedb_json-0.3.0 → pybasedb_json-0.5.0}/pybase/backup.py +3 -2
- pybasedb_json-0.5.0/pybase/cli/__init__.py +3 -0
- pybasedb_json-0.5.0/pybase/cli/colors.py +122 -0
- pybasedb_json-0.5.0/pybase/cli/commands.py +256 -0
- pybasedb_json-0.5.0/pybase/cli/format.py +92 -0
- pybasedb_json-0.5.0/pybase/cli/main.py +151 -0
- pybasedb_json-0.5.0/pybase/collections.py +473 -0
- pybasedb_json-0.5.0/pybase/crypto.py +59 -0
- pybasedb_json-0.5.0/pybase/database.py +178 -0
- pybasedb_json-0.5.0/pybase/exceptions.py +30 -0
- pybasedb_json-0.5.0/pybase/filters.py +66 -0
- {pybasedb_json-0.3.0 → pybasedb_json-0.5.0}/pybase/hooks.py +50 -35
- pybasedb_json-0.5.0/pybase/index.py +102 -0
- pybasedb_json-0.5.0/pybase/lock.py +48 -0
- {pybasedb_json-0.3.0 → pybasedb_json-0.5.0}/pybase/media.py +2 -2
- pybasedb_json-0.5.0/pybase/migration.py +47 -0
- pybasedb_json-0.5.0/pybase/plugin.py +48 -0
- pybasedb_json-0.5.0/pybase/pybase.py +57 -0
- pybasedb_json-0.5.0/pybase/query.py +33 -0
- pybasedb_json-0.5.0/pybase/ref.py +31 -0
- pybasedb_json-0.5.0/pybase/server.py +355 -0
- pybasedb_json-0.5.0/pybase/transaction.py +51 -0
- pybasedb_json-0.5.0/pybase/utils.py +23 -0
- pybasedb_json-0.5.0/pybase/validation.py +655 -0
- pybasedb_json-0.5.0/pybasedb_json.egg-info/PKG-INFO +173 -0
- pybasedb_json-0.5.0/pybasedb_json.egg-info/SOURCES.txt +34 -0
- pybasedb_json-0.5.0/pybasedb_json.egg-info/entry_points.txt +2 -0
- {pybasedb_json-0.3.0 → pybasedb_json-0.5.0}/pyproject.toml +5 -2
- pybasedb_json-0.3.0/PKG-INFO +0 -134
- pybasedb_json-0.3.0/README.md +0 -108
- pybasedb_json-0.3.0/pybase/__init__.py +0 -29
- pybasedb_json-0.3.0/pybase/collections.py +0 -218
- pybasedb_json-0.3.0/pybase/database.py +0 -106
- pybasedb_json-0.3.0/pybase/exceptions.py +0 -14
- pybasedb_json-0.3.0/pybase/index.py +0 -54
- pybasedb_json-0.3.0/pybase/query.py +0 -89
- pybasedb_json-0.3.0/pybase/server.py +0 -279
- pybasedb_json-0.3.0/pybase/utils.py +0 -8
- pybasedb_json-0.3.0/pybase/validation.py +0 -236
- pybasedb_json-0.3.0/pybasedb_json.egg-info/PKG-INFO +0 -134
- pybasedb_json-0.3.0/pybasedb_json.egg-info/SOURCES.txt +0 -18
- {pybasedb_json-0.3.0 → pybasedb_json-0.5.0}/pybasedb_json.egg-info/dependency_links.txt +0 -0
- {pybasedb_json-0.3.0 → pybasedb_json-0.5.0}/pybasedb_json.egg-info/top_level.txt +0 -0
- {pybasedb_json-0.3.0 → pybasedb_json-0.5.0}/setup.cfg +0 -0
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: pybasedb-json
|
|
3
|
+
Version: 0.5.0
|
|
4
|
+
Summary: Banco de dados local com JSON — schemas, decorator API, server REST, criptografia, zero dependencias
|
|
5
|
+
Author-email: Marcos Gomes <marcosgabrielgomes110@gmail.com>
|
|
6
|
+
Maintainer-email: Marcos Gomes <marcosgabrielgomes110@gmail.com>
|
|
7
|
+
License: MIT
|
|
8
|
+
Project-URL: Homepage, https://github.com/marcosgabrielgomes110-collab/Pybase
|
|
9
|
+
Project-URL: Documentation, https://github.com/marcosgabrielgomes110-collab/Pybase/tree/main/docs
|
|
10
|
+
Project-URL: Repository, https://github.com/marcosgabrielgomes110-collab/Pybase
|
|
11
|
+
Keywords: database,json,local,embedded,nosql,thread-safe,rest-api,schema,media
|
|
12
|
+
Classifier: Development Status :: 4 - Beta
|
|
13
|
+
Classifier: Intended Audience :: Developers
|
|
14
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
15
|
+
Classifier: Programming Language :: Python :: 3
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
21
|
+
Classifier: Topic :: Database
|
|
22
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
23
|
+
Classifier: Topic :: Internet :: WWW/HTTP :: HTTP Servers
|
|
24
|
+
Requires-Python: >=3.10
|
|
25
|
+
Description-Content-Type: text/markdown
|
|
26
|
+
|
|
27
|
+
<p align="center">
|
|
28
|
+
<img src="assets/logo/logo.png" width="120" alt="Pybase logo">
|
|
29
|
+
</p>
|
|
30
|
+
|
|
31
|
+
# Pybase v0.5
|
|
32
|
+
|
|
33
|
+
Base para criacao de bancos de dados locais com JSON. Zero dependencias, 100% stdlib.
|
|
34
|
+
Operacoes de escrita atomicas, thread-safe.
|
|
35
|
+
|
|
36
|
+
Filosofia **Lego**: cada modulo e independente — voce monta o que precisa.
|
|
37
|
+
|
|
38
|
+
## Instalacao
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
pip install pybasedb-json
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
Para o servidor REST (opcional):
|
|
45
|
+
```bash
|
|
46
|
+
pip install Flask
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
## Uso rapido
|
|
50
|
+
|
|
51
|
+
```python
|
|
52
|
+
from pybase import pybase as pb
|
|
53
|
+
|
|
54
|
+
# Banco de dados
|
|
55
|
+
db = pb.Database("./data/mydb")
|
|
56
|
+
|
|
57
|
+
# Schema com decorator
|
|
58
|
+
@db.schema.users
|
|
59
|
+
class User:
|
|
60
|
+
name: str
|
|
61
|
+
email: str
|
|
62
|
+
age: int = 0
|
|
63
|
+
active: bool = True
|
|
64
|
+
tags: list[str] = []
|
|
65
|
+
|
|
66
|
+
# Colecao com validacao automatica
|
|
67
|
+
users = db["users"]
|
|
68
|
+
users.add({"name": "marcos", "email": "m@m.com"})
|
|
69
|
+
|
|
70
|
+
# Operadores de query (v0.5+)
|
|
71
|
+
users.find(age__gt=18, name__contains="mar")
|
|
72
|
+
|
|
73
|
+
# Paginacao (v0.5+)
|
|
74
|
+
users.paginate(page=1, per_page=20)
|
|
75
|
+
|
|
76
|
+
# Transacao (v0.5+)
|
|
77
|
+
with db.transaction() as txn:
|
|
78
|
+
txn["users"].add({"name": "ana"})
|
|
79
|
+
|
|
80
|
+
# Server com auth + CORS (v0.5+)
|
|
81
|
+
pb.Server(db, auth="token123", cors="*").run()
|
|
82
|
+
|
|
83
|
+
# CLI (v0.5+)
|
|
84
|
+
# $ pybase serve mydb --port=4560
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
## Modulos
|
|
88
|
+
|
|
89
|
+
| Modulo | Arquivo | Descricao | Deps |
|
|
90
|
+
|--------|---------|-----------|------|
|
|
91
|
+
| Database | `pybase/database.py` | Gerencia diretorio de tabelas JSON | 0 |
|
|
92
|
+
| Collection | `pybase/collections.py` | CRUD atomico + query com operadores + JSONL | 0 |
|
|
93
|
+
| Filter | `pybase/filters.py` | Motor de filtros com 13 operadores | 0 |
|
|
94
|
+
| Query | `pybase/query.py` | Thin wrapper sobre Collection | 0 |
|
|
95
|
+
| Schema | `pybase/validation.py` | Validacao com choices, min/max, email, datetime, UUID, ref, JSON Schema | 0 |
|
|
96
|
+
| Ref | `pybase/ref.py` | Referencias entre colecoes | 0 |
|
|
97
|
+
| Server | `pybase/server.py` | REST API com auth, cors, patch, batch + Swagger UI | Flask |
|
|
98
|
+
| CLI | `pybase/cli/` | Linha de comando: init, inspect, serve, backup (ASCII + ANSI) | 0 |
|
|
99
|
+
| Media | `pybase/media.py` | Upload/download de imagens | 0 |
|
|
100
|
+
| Backup | `pybase/backup.py` | Snapshot e restore (seletivo) | 0 |
|
|
101
|
+
| Crypto | `pybase/crypto.py` | Criptografia stdlib (scrypt + XOR) | 0 |
|
|
102
|
+
| Hooks | `pybase/hooks.py` | Lifecycle hooks para Collection | 0 |
|
|
103
|
+
| Plugin | `pybase/plugin.py` | Sistema de plugins globais | 0 |
|
|
104
|
+
| Transaction | `pybase/transaction.py` | Multi-colecao commit/rollback | 0 |
|
|
105
|
+
| Migration | `pybase/migration.py` | Migracoes versionadas | 0 |
|
|
106
|
+
| Async | `pybase/async_.py` | Wrappers assincronos | 0 |
|
|
107
|
+
| Index | `pybase/index.py` | Indices hash O(1) (memoria + persistente) | 0 |
|
|
108
|
+
|
|
109
|
+
## Novidades da v0.5
|
|
110
|
+
|
|
111
|
+
- **Operadores de query** — `__gt`, `__contains`, `__in`, `__has`, `__regex` e mais 13
|
|
112
|
+
- **Paginacao** — `.paginate(page, per_page)` → `{items, total, pages}`
|
|
113
|
+
- **Projecao** — `.select("name", "age")` para campos especificos
|
|
114
|
+
- **Agregacao** — `.aggregate([$match, $group, $sort, ...])`
|
|
115
|
+
- **Schema avancado** — `choices`, `min`/`max`, `email`, `url`, `datetime`, `UUID`, `ref`
|
|
116
|
+
- **Ref** — `Ref("users", "abc").resolve(db)` para referencias entre colecoes
|
|
117
|
+
- **JSON Schema** — `.to_json_schema()` export draft-07
|
|
118
|
+
- **CLI** — `pybase init`, `inspect`, `serve`, `backup`, `query`, `schema`, ...
|
|
119
|
+
- **Server auth** — `Server(db, auth="token")`, Basic Auth, callback
|
|
120
|
+
- **Server CORS** — `Server(db, cors="*")` ou lista de origens
|
|
121
|
+
- **PATCH** — atualizacao parcial via REST
|
|
122
|
+
- **Batch** — operacoes em lote via REST
|
|
123
|
+
- **Transacoes** — `with db.transaction() as txn:` commit/rollback
|
|
124
|
+
- **Plugins** — `Plugin` class com `on_add`, `on_update`, etc
|
|
125
|
+
- **Migracoes** — `Migration(db).add(ver, fn).run()`
|
|
126
|
+
- **Async** — `AsyncCollection`, `AsyncDatabase` (via `asyncio.to_thread`)
|
|
127
|
+
- **Eventos** — `col.on("add", cb)` observer pattern
|
|
128
|
+
- **JSONL** — formato linha-por-linha para append O(1)
|
|
129
|
+
- **Lock multi-processo** — `Collection(lock_type="process")`
|
|
130
|
+
- **PersistentIndex** — indice salvo em disco
|
|
131
|
+
- **Clone** — `db.clone(dest)` copia banco
|
|
132
|
+
- **Context manager** — `with Database(...) as db:`
|
|
133
|
+
|
|
134
|
+
## Estrutura
|
|
135
|
+
|
|
136
|
+
```
|
|
137
|
+
Pybase/
|
|
138
|
+
pybase/
|
|
139
|
+
__init__.py # Database, Collection, Query, Server, Schema, T, Filter, Ref
|
|
140
|
+
__main__.py # python -m pybase
|
|
141
|
+
pybase.py # from pybase import pybase
|
|
142
|
+
database.py # Database, SchemaRegistrar
|
|
143
|
+
collections.py # Collection, DocRef, QueryBuilder, SchemaCollection
|
|
144
|
+
filters.py # Filter: operadores de query
|
|
145
|
+
query.py # Query wrapper
|
|
146
|
+
exceptions.py # PybaseError > DatabaseError, CollectionError, ...
|
|
147
|
+
validation.py # Schema, T, ValidationError
|
|
148
|
+
ref.py # Ref: referencias entre colecoes
|
|
149
|
+
server.py # Server REST (Flask) com auth/cors/patch/batch
|
|
150
|
+
cli/ # CLI: init, inspect, serve, backup (ASCII + ANSI)
|
|
151
|
+
media.py # MediaManager
|
|
152
|
+
index.py # Index + PersistentIndex
|
|
153
|
+
hooks.py # HooksCollection
|
|
154
|
+
backup.py # take, restore
|
|
155
|
+
crypto.py # encrypt, decrypt (stdlib)
|
|
156
|
+
plugin.py # Plugin system
|
|
157
|
+
transaction.py # Transaction commit/rollback
|
|
158
|
+
migration.py # Migration versionada
|
|
159
|
+
async_.py # AsyncCollection, AsyncDatabase
|
|
160
|
+
lock.py # FileLock multi-processo
|
|
161
|
+
utils.py # PBKDF2 encode/verify
|
|
162
|
+
docs/ # Documentacao completa (23 paginas)
|
|
163
|
+
index.html # Documentacao web
|
|
164
|
+
pyproject.toml
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
## Documentacao
|
|
168
|
+
|
|
169
|
+
Veja [docs/](docs/index.md) ou [index.html](index.html) com referencia completa de cada classe e metodo.
|
|
170
|
+
|
|
171
|
+
## Licenca
|
|
172
|
+
|
|
173
|
+
MIT
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
<p align="center">
|
|
2
|
+
<img src="assets/logo/logo.png" width="120" alt="Pybase logo">
|
|
3
|
+
</p>
|
|
4
|
+
|
|
5
|
+
# Pybase v0.5
|
|
6
|
+
|
|
7
|
+
Base para criacao de bancos de dados locais com JSON. Zero dependencias, 100% stdlib.
|
|
8
|
+
Operacoes de escrita atomicas, thread-safe.
|
|
9
|
+
|
|
10
|
+
Filosofia **Lego**: cada modulo e independente — voce monta o que precisa.
|
|
11
|
+
|
|
12
|
+
## Instalacao
|
|
13
|
+
|
|
14
|
+
```bash
|
|
15
|
+
pip install pybasedb-json
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
Para o servidor REST (opcional):
|
|
19
|
+
```bash
|
|
20
|
+
pip install Flask
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
## Uso rapido
|
|
24
|
+
|
|
25
|
+
```python
|
|
26
|
+
from pybase import pybase as pb
|
|
27
|
+
|
|
28
|
+
# Banco de dados
|
|
29
|
+
db = pb.Database("./data/mydb")
|
|
30
|
+
|
|
31
|
+
# Schema com decorator
|
|
32
|
+
@db.schema.users
|
|
33
|
+
class User:
|
|
34
|
+
name: str
|
|
35
|
+
email: str
|
|
36
|
+
age: int = 0
|
|
37
|
+
active: bool = True
|
|
38
|
+
tags: list[str] = []
|
|
39
|
+
|
|
40
|
+
# Colecao com validacao automatica
|
|
41
|
+
users = db["users"]
|
|
42
|
+
users.add({"name": "marcos", "email": "m@m.com"})
|
|
43
|
+
|
|
44
|
+
# Operadores de query (v0.5+)
|
|
45
|
+
users.find(age__gt=18, name__contains="mar")
|
|
46
|
+
|
|
47
|
+
# Paginacao (v0.5+)
|
|
48
|
+
users.paginate(page=1, per_page=20)
|
|
49
|
+
|
|
50
|
+
# Transacao (v0.5+)
|
|
51
|
+
with db.transaction() as txn:
|
|
52
|
+
txn["users"].add({"name": "ana"})
|
|
53
|
+
|
|
54
|
+
# Server com auth + CORS (v0.5+)
|
|
55
|
+
pb.Server(db, auth="token123", cors="*").run()
|
|
56
|
+
|
|
57
|
+
# CLI (v0.5+)
|
|
58
|
+
# $ pybase serve mydb --port=4560
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
## Modulos
|
|
62
|
+
|
|
63
|
+
| Modulo | Arquivo | Descricao | Deps |
|
|
64
|
+
|--------|---------|-----------|------|
|
|
65
|
+
| Database | `pybase/database.py` | Gerencia diretorio de tabelas JSON | 0 |
|
|
66
|
+
| Collection | `pybase/collections.py` | CRUD atomico + query com operadores + JSONL | 0 |
|
|
67
|
+
| Filter | `pybase/filters.py` | Motor de filtros com 13 operadores | 0 |
|
|
68
|
+
| Query | `pybase/query.py` | Thin wrapper sobre Collection | 0 |
|
|
69
|
+
| Schema | `pybase/validation.py` | Validacao com choices, min/max, email, datetime, UUID, ref, JSON Schema | 0 |
|
|
70
|
+
| Ref | `pybase/ref.py` | Referencias entre colecoes | 0 |
|
|
71
|
+
| Server | `pybase/server.py` | REST API com auth, cors, patch, batch + Swagger UI | Flask |
|
|
72
|
+
| CLI | `pybase/cli/` | Linha de comando: init, inspect, serve, backup (ASCII + ANSI) | 0 |
|
|
73
|
+
| Media | `pybase/media.py` | Upload/download de imagens | 0 |
|
|
74
|
+
| Backup | `pybase/backup.py` | Snapshot e restore (seletivo) | 0 |
|
|
75
|
+
| Crypto | `pybase/crypto.py` | Criptografia stdlib (scrypt + XOR) | 0 |
|
|
76
|
+
| Hooks | `pybase/hooks.py` | Lifecycle hooks para Collection | 0 |
|
|
77
|
+
| Plugin | `pybase/plugin.py` | Sistema de plugins globais | 0 |
|
|
78
|
+
| Transaction | `pybase/transaction.py` | Multi-colecao commit/rollback | 0 |
|
|
79
|
+
| Migration | `pybase/migration.py` | Migracoes versionadas | 0 |
|
|
80
|
+
| Async | `pybase/async_.py` | Wrappers assincronos | 0 |
|
|
81
|
+
| Index | `pybase/index.py` | Indices hash O(1) (memoria + persistente) | 0 |
|
|
82
|
+
|
|
83
|
+
## Novidades da v0.5
|
|
84
|
+
|
|
85
|
+
- **Operadores de query** — `__gt`, `__contains`, `__in`, `__has`, `__regex` e mais 13
|
|
86
|
+
- **Paginacao** — `.paginate(page, per_page)` → `{items, total, pages}`
|
|
87
|
+
- **Projecao** — `.select("name", "age")` para campos especificos
|
|
88
|
+
- **Agregacao** — `.aggregate([$match, $group, $sort, ...])`
|
|
89
|
+
- **Schema avancado** — `choices`, `min`/`max`, `email`, `url`, `datetime`, `UUID`, `ref`
|
|
90
|
+
- **Ref** — `Ref("users", "abc").resolve(db)` para referencias entre colecoes
|
|
91
|
+
- **JSON Schema** — `.to_json_schema()` export draft-07
|
|
92
|
+
- **CLI** — `pybase init`, `inspect`, `serve`, `backup`, `query`, `schema`, ...
|
|
93
|
+
- **Server auth** — `Server(db, auth="token")`, Basic Auth, callback
|
|
94
|
+
- **Server CORS** — `Server(db, cors="*")` ou lista de origens
|
|
95
|
+
- **PATCH** — atualizacao parcial via REST
|
|
96
|
+
- **Batch** — operacoes em lote via REST
|
|
97
|
+
- **Transacoes** — `with db.transaction() as txn:` commit/rollback
|
|
98
|
+
- **Plugins** — `Plugin` class com `on_add`, `on_update`, etc
|
|
99
|
+
- **Migracoes** — `Migration(db).add(ver, fn).run()`
|
|
100
|
+
- **Async** — `AsyncCollection`, `AsyncDatabase` (via `asyncio.to_thread`)
|
|
101
|
+
- **Eventos** — `col.on("add", cb)` observer pattern
|
|
102
|
+
- **JSONL** — formato linha-por-linha para append O(1)
|
|
103
|
+
- **Lock multi-processo** — `Collection(lock_type="process")`
|
|
104
|
+
- **PersistentIndex** — indice salvo em disco
|
|
105
|
+
- **Clone** — `db.clone(dest)` copia banco
|
|
106
|
+
- **Context manager** — `with Database(...) as db:`
|
|
107
|
+
|
|
108
|
+
## Estrutura
|
|
109
|
+
|
|
110
|
+
```
|
|
111
|
+
Pybase/
|
|
112
|
+
pybase/
|
|
113
|
+
__init__.py # Database, Collection, Query, Server, Schema, T, Filter, Ref
|
|
114
|
+
__main__.py # python -m pybase
|
|
115
|
+
pybase.py # from pybase import pybase
|
|
116
|
+
database.py # Database, SchemaRegistrar
|
|
117
|
+
collections.py # Collection, DocRef, QueryBuilder, SchemaCollection
|
|
118
|
+
filters.py # Filter: operadores de query
|
|
119
|
+
query.py # Query wrapper
|
|
120
|
+
exceptions.py # PybaseError > DatabaseError, CollectionError, ...
|
|
121
|
+
validation.py # Schema, T, ValidationError
|
|
122
|
+
ref.py # Ref: referencias entre colecoes
|
|
123
|
+
server.py # Server REST (Flask) com auth/cors/patch/batch
|
|
124
|
+
cli/ # CLI: init, inspect, serve, backup (ASCII + ANSI)
|
|
125
|
+
media.py # MediaManager
|
|
126
|
+
index.py # Index + PersistentIndex
|
|
127
|
+
hooks.py # HooksCollection
|
|
128
|
+
backup.py # take, restore
|
|
129
|
+
crypto.py # encrypt, decrypt (stdlib)
|
|
130
|
+
plugin.py # Plugin system
|
|
131
|
+
transaction.py # Transaction commit/rollback
|
|
132
|
+
migration.py # Migration versionada
|
|
133
|
+
async_.py # AsyncCollection, AsyncDatabase
|
|
134
|
+
lock.py # FileLock multi-processo
|
|
135
|
+
utils.py # PBKDF2 encode/verify
|
|
136
|
+
docs/ # Documentacao completa (23 paginas)
|
|
137
|
+
index.html # Documentacao web
|
|
138
|
+
pyproject.toml
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
## Documentacao
|
|
142
|
+
|
|
143
|
+
Veja [docs/](docs/index.md) ou [index.html](index.html) com referencia completa de cada classe e metodo.
|
|
144
|
+
|
|
145
|
+
## Licenca
|
|
146
|
+
|
|
147
|
+
MIT
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
try:
|
|
2
|
+
from .server import Server
|
|
3
|
+
except ImportError:
|
|
4
|
+
Server = None
|
|
5
|
+
|
|
6
|
+
from .collections import Collection, DocRef, QueryBuilder, SchemaCollection
|
|
7
|
+
from .database import Database
|
|
8
|
+
from .filters import Filter
|
|
9
|
+
from .ref import Ref
|
|
10
|
+
from .exceptions import (
|
|
11
|
+
CollectionError,
|
|
12
|
+
DatabaseError,
|
|
13
|
+
DocumentNotFoundError,
|
|
14
|
+
EncryptionError,
|
|
15
|
+
MediaError,
|
|
16
|
+
PybaseError,
|
|
17
|
+
QueryError,
|
|
18
|
+
ValidationError,
|
|
19
|
+
)
|
|
20
|
+
from .query import Query
|
|
21
|
+
|
|
22
|
+
try:
|
|
23
|
+
from .validation import Schema, T
|
|
24
|
+
except ImportError:
|
|
25
|
+
Schema = None
|
|
26
|
+
T = None
|
|
27
|
+
|
|
28
|
+
__all__ = [
|
|
29
|
+
"Collection",
|
|
30
|
+
"Database",
|
|
31
|
+
"DocRef",
|
|
32
|
+
"DocumentNotFoundError",
|
|
33
|
+
"EncryptionError",
|
|
34
|
+
"MediaError",
|
|
35
|
+
"PybaseError",
|
|
36
|
+
"DatabaseError",
|
|
37
|
+
"CollectionError",
|
|
38
|
+
"Filter",
|
|
39
|
+
"Query",
|
|
40
|
+
"QueryBuilder",
|
|
41
|
+
"QueryError",
|
|
42
|
+
"Ref",
|
|
43
|
+
"Schema",
|
|
44
|
+
"SchemaCollection",
|
|
45
|
+
"Server",
|
|
46
|
+
"T",
|
|
47
|
+
"ValidationError",
|
|
48
|
+
]
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import asyncio
|
|
4
|
+
from typing import Any
|
|
5
|
+
|
|
6
|
+
from .collections import Collection as SyncCollection
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class AsyncCollection:
|
|
10
|
+
def __init__(self, collection: SyncCollection) -> None:
|
|
11
|
+
self._col = collection
|
|
12
|
+
|
|
13
|
+
async def all(self) -> list[dict]:
|
|
14
|
+
return await asyncio.to_thread(self._col.all)
|
|
15
|
+
|
|
16
|
+
async def get(self, doc_id: str) -> dict | None:
|
|
17
|
+
return await asyncio.to_thread(self._col.get, doc_id)
|
|
18
|
+
|
|
19
|
+
async def add(self, data: dict) -> dict:
|
|
20
|
+
return await asyncio.to_thread(self._col.add, data)
|
|
21
|
+
|
|
22
|
+
async def add_many(self, items: list[dict]) -> list[dict]:
|
|
23
|
+
return await asyncio.to_thread(self._col.add_many, items)
|
|
24
|
+
|
|
25
|
+
async def update(self, data: dict, **match) -> int:
|
|
26
|
+
return await asyncio.to_thread(self._col.update, data, **match)
|
|
27
|
+
|
|
28
|
+
async def delete(self, **match) -> int:
|
|
29
|
+
return await asyncio.to_thread(self._col.delete, **match)
|
|
30
|
+
|
|
31
|
+
async def find(self, **match) -> list[dict]:
|
|
32
|
+
return await asyncio.to_thread(self._col.find, **match)
|
|
33
|
+
|
|
34
|
+
async def find_one(self, **match) -> dict | None:
|
|
35
|
+
return await asyncio.to_thread(self._col.find_one, **match)
|
|
36
|
+
|
|
37
|
+
async def exists(self, **match) -> bool:
|
|
38
|
+
return await asyncio.to_thread(self._col.exists, **match)
|
|
39
|
+
|
|
40
|
+
async def count(self, **match) -> int:
|
|
41
|
+
return await asyncio.to_thread(self._col.count, **match)
|
|
42
|
+
|
|
43
|
+
async def paginate(self, page: int = 1, per_page: int = 20) -> dict:
|
|
44
|
+
return await asyncio.to_thread(self._col.paginate, page, per_page)
|
|
45
|
+
|
|
46
|
+
def __getattr__(self, name: str):
|
|
47
|
+
return getattr(self._col, name)
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
class AsyncDatabase:
|
|
51
|
+
def __init__(self, db) -> None:
|
|
52
|
+
self._db = db
|
|
53
|
+
|
|
54
|
+
@property
|
|
55
|
+
def name(self) -> str:
|
|
56
|
+
return self._db.name
|
|
57
|
+
|
|
58
|
+
@property
|
|
59
|
+
def collections(self) -> list[str]:
|
|
60
|
+
return self._db.collections
|
|
61
|
+
|
|
62
|
+
def collection(self, name: str) -> AsyncCollection:
|
|
63
|
+
return AsyncCollection(self._db.collection(name))
|
|
64
|
+
|
|
65
|
+
async def info(self) -> dict:
|
|
66
|
+
return await asyncio.to_thread(self._db.info)
|
|
@@ -22,8 +22,8 @@ def take(
|
|
|
22
22
|
dest: str | Path | None = None,
|
|
23
23
|
*,
|
|
24
24
|
compress: bool = True,
|
|
25
|
+
collections: list[str] | None = None,
|
|
25
26
|
) -> Path:
|
|
26
|
-
# Snapshot every collection into one timestamped file
|
|
27
27
|
backup_dir = Path(dest) if dest else (db.path_dir / _BACKUP_DIR)
|
|
28
28
|
backup_dir.mkdir(parents=True, exist_ok=True)
|
|
29
29
|
|
|
@@ -31,8 +31,9 @@ def take(
|
|
|
31
31
|
ext = ".json.gz" if compress else ".json"
|
|
32
32
|
out_path = backup_dir / f"{db.name}_{ts}{ext}"
|
|
33
33
|
|
|
34
|
+
names = collections if collections else db.collections
|
|
34
35
|
snapshot: dict[str, list[dict]] = {}
|
|
35
|
-
for name in
|
|
36
|
+
for name in names:
|
|
36
37
|
snapshot[name] = db.collection(name).all()
|
|
37
38
|
|
|
38
39
|
raw = json.dumps(snapshot, indent=2).encode("utf-8")
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
import os
|
|
2
|
+
|
|
3
|
+
_RESET = "\033[0m"
|
|
4
|
+
_BOLD = "\033[1m"
|
|
5
|
+
_DIM = "\033[2m"
|
|
6
|
+
_ITALIC = "\033[3m"
|
|
7
|
+
_UNDERLINE = "\033[4m"
|
|
8
|
+
_REVERSE = "\033[7m"
|
|
9
|
+
|
|
10
|
+
_BLACK = "\033[30m"
|
|
11
|
+
_RED = "\033[31m"
|
|
12
|
+
_GREEN = "\033[32m"
|
|
13
|
+
_YELLOW = "\033[33m"
|
|
14
|
+
_BLUE = "\033[34m"
|
|
15
|
+
_MAGENTA = "\033[35m"
|
|
16
|
+
_CYAN = "\033[36m"
|
|
17
|
+
_WHITE = "\033[37m"
|
|
18
|
+
|
|
19
|
+
_BG_BLACK = "\033[40m"
|
|
20
|
+
_BG_RED = "\033[41m"
|
|
21
|
+
_BG_GREEN = "\033[42m"
|
|
22
|
+
_BG_YELLOW = "\033[43m"
|
|
23
|
+
_BG_BLUE = "\033[44m"
|
|
24
|
+
_BG_MAGENTA = "\033[45m"
|
|
25
|
+
_BG_CYAN = "\033[46m"
|
|
26
|
+
_BG_WHITE = "\033[47m"
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
def _supports_color() -> bool:
|
|
30
|
+
return os.environ.get("NO_COLOR") is None and (
|
|
31
|
+
os.environ.get("TERM") not in ("dumb", "") or os.isatty(1)
|
|
32
|
+
)
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
def s(text: str, *codes: str) -> str:
|
|
36
|
+
if not codes or not _supports_color():
|
|
37
|
+
return text
|
|
38
|
+
return "".join(codes) + text + _RESET
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
def bold(text: str) -> str:
|
|
42
|
+
return s(text, _BOLD)
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
def dim(text: str) -> str:
|
|
46
|
+
return s(text, _DIM)
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
def red(text: str) -> str:
|
|
50
|
+
return s(text, _RED)
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
def green(text: str) -> str:
|
|
54
|
+
return s(text, _GREEN)
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
def yellow(text: str) -> str:
|
|
58
|
+
return s(text, _YELLOW)
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
def blue(text: str) -> str:
|
|
62
|
+
return s(text, _BLUE)
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
def magenta(text: str) -> str:
|
|
66
|
+
return s(text, _MAGENTA)
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
def cyan(text: str) -> str:
|
|
70
|
+
return s(text, _CYAN)
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
def white(text: str) -> str:
|
|
74
|
+
return s(text, _WHITE)
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
def bold_red(text: str) -> str:
|
|
78
|
+
return s(text, _BOLD, _RED)
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
def bold_green(text: str) -> str:
|
|
82
|
+
return s(text, _BOLD, _GREEN)
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
def bold_yellow(text: str) -> str:
|
|
86
|
+
return s(text, _BOLD, _YELLOW)
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
def bold_blue(text: str) -> str:
|
|
90
|
+
return s(text, _BOLD, _BLUE)
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
def bold_cyan(text: str) -> str:
|
|
94
|
+
return s(text, _BOLD, _CYAN)
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
def bold_magenta(text: str) -> str:
|
|
98
|
+
return s(text, _BOLD, _MAGENTA)
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
def header(text: str) -> str:
|
|
102
|
+
return s(text, _BOLD, _WHITE, _BG_BLUE)
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
def ok(text: str) -> str:
|
|
106
|
+
return s(text, _BOLD, _GREEN)
|
|
107
|
+
|
|
108
|
+
|
|
109
|
+
def warn(text: str) -> str:
|
|
110
|
+
return s(text, _BOLD, _YELLOW)
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
def fail(text: str) -> str:
|
|
114
|
+
return s(text, _BOLD, _RED)
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
def info(text: str) -> str:
|
|
118
|
+
return s(text, _CYAN)
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
def muted(text: str) -> str:
|
|
122
|
+
return s(text, _DIM)
|