cloudoll 4.2.1__tar.gz → 4.4.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.
- cloudoll-4.4.0/CHANGELOG.md +220 -0
- {cloudoll-4.2.1 → cloudoll-4.4.0}/PKG-INFO +8 -7
- {cloudoll-4.2.1 → cloudoll-4.4.0}/README.md +7 -6
- {cloudoll-4.2.1 → cloudoll-4.4.0}/README.zh-CN.md +11 -11
- cloudoll-4.4.0/cloudoll/__init__.py +1 -0
- {cloudoll-4.2.1 → cloudoll-4.4.0}/cloudoll/ai/AGENTS.md +4 -0
- {cloudoll-4.2.1 → cloudoll-4.4.0}/cloudoll/ai/docs/ai.md +2 -0
- {cloudoll-4.2.1 → cloudoll-4.4.0}/cloudoll/ai/docs/changelog.md +65 -3
- {cloudoll-4.2.1 → cloudoll-4.4.0}/cloudoll/ai/docs/config.md +14 -2
- {cloudoll-4.2.1 → cloudoll-4.4.0}/cloudoll/ai/docs/cookie-and-session.md +6 -1
- {cloudoll-4.2.1 → cloudoll-4.4.0}/cloudoll/ai/docs/database.md +255 -23
- {cloudoll-4.2.1 → cloudoll-4.4.0}/cloudoll/ai/docs/jwt.md +9 -2
- cloudoll-4.4.0/cloudoll/ai/docs/mail.md +74 -0
- {cloudoll-4.2.1 → cloudoll-4.4.0}/cloudoll/ai/docs/start.md +7 -5
- cloudoll-4.4.0/cloudoll/ai/docs/utils.md +74 -0
- {cloudoll-4.2.1 → cloudoll-4.4.0}/cloudoll/ai/docs/view.md +3 -1
- {cloudoll-4.2.1 → cloudoll-4.4.0}/cloudoll/ai/manifest.json +19 -9
- {cloudoll-4.2.1 → cloudoll-4.4.0}/cloudoll/ai/skills/cloudoll/SKILL.md +11 -1
- {cloudoll-4.2.1 → cloudoll-4.4.0}/cloudoll/cli.py +7 -1
- {cloudoll-4.2.1 → cloudoll-4.4.0}/cloudoll/clitool/cli_main.py +67 -26
- {cloudoll-4.2.1 → cloudoll-4.4.0}/cloudoll/clitool/watch.py +37 -2
- {cloudoll-4.2.1 → cloudoll-4.4.0}/cloudoll/mail/smtp.py +39 -53
- {cloudoll-4.2.1 → cloudoll-4.4.0}/cloudoll/orm/__init__.py +18 -1
- {cloudoll-4.2.1 → cloudoll-4.4.0}/cloudoll/orm/aws_engine.py +3 -0
- {cloudoll-4.2.1 → cloudoll-4.4.0}/cloudoll/orm/compiler.py +167 -10
- {cloudoll-4.2.1 → cloudoll-4.4.0}/cloudoll/orm/engine.py +17 -3
- {cloudoll-4.2.1 → cloudoll-4.4.0}/cloudoll/orm/field.py +3 -0
- {cloudoll-4.2.1 → cloudoll-4.4.0}/cloudoll/orm/model.py +20 -0
- {cloudoll-4.2.1 → cloudoll-4.4.0}/cloudoll/orm/protocols.py +1 -0
- {cloudoll-4.2.1 → cloudoll-4.4.0}/cloudoll/orm/query.py +237 -9
- cloudoll-4.4.0/cloudoll/orm/relation.py +79 -0
- {cloudoll-4.2.1 → cloudoll-4.4.0}/cloudoll/orm/savepoints.py +4 -0
- cloudoll-4.4.0/cloudoll/orm/subquery.py +15 -0
- cloudoll-4.4.0/cloudoll/template/.gitignore +82 -0
- {cloudoll-4.2.1 → cloudoll-4.4.0}/cloudoll/template/README.md +11 -1
- {cloudoll-4.2.1 → cloudoll-4.4.0}/cloudoll/template/config/conf.local.yaml +10 -2
- cloudoll-4.4.0/cloudoll/template/middlewares/auth.py +38 -0
- cloudoll-4.4.0/cloudoll/template/requirements.txt +1 -0
- {cloudoll-4.2.1 → cloudoll-4.4.0}/cloudoll/web/configuration.py +12 -0
- {cloudoll-4.2.1 → cloudoll-4.4.0}/cloudoll/web/core.py +45 -9
- {cloudoll-4.2.1 → cloudoll-4.4.0}/cloudoll/web/sessions.py +15 -20
- {cloudoll-4.2.1 → cloudoll-4.4.0}/cloudoll.egg-info/PKG-INFO +8 -7
- {cloudoll-4.2.1 → cloudoll-4.4.0}/cloudoll.egg-info/SOURCES.txt +9 -0
- {cloudoll-4.2.1 → cloudoll-4.4.0}/docs/maintenance.md +2 -0
- {cloudoll-4.2.1 → cloudoll-4.4.0}/pyproject.toml +1 -0
- {cloudoll-4.2.1 → cloudoll-4.4.0}/tests/check_wheel.py +5 -0
- cloudoll-4.4.0/tests/integration/test_databases.py +576 -0
- cloudoll-4.4.0/tests/test_cli_create.py +192 -0
- {cloudoll-4.2.1 → cloudoll-4.4.0}/tests/test_datasources.py +28 -0
- {cloudoll-4.2.1 → cloudoll-4.4.0}/tests/test_dev_lifecycle.py +203 -3
- {cloudoll-4.2.1 → cloudoll-4.4.0}/tests/test_field_types.py +11 -0
- cloudoll-4.4.0/tests/test_mail_client.py +183 -0
- cloudoll-4.4.0/tests/test_password_and_id_utils.py +151 -0
- cloudoll-4.4.0/tests/test_query_capabilities.py +225 -0
- {cloudoll-4.2.1 → cloudoll-4.4.0}/tests/test_regressions.py +46 -7
- {cloudoll-4.2.1 → cloudoll-4.4.0}/tests/test_request_contract.py +152 -1
- {cloudoll-4.2.1 → cloudoll-4.4.0}/tests/test_transactions.py +60 -0
- {cloudoll-4.2.1 → cloudoll-4.4.0}/tests/typing/query_contract.py +14 -1
- cloudoll-4.2.1/CHANGELOG.md +0 -106
- cloudoll-4.2.1/cloudoll/__init__.py +0 -1
- cloudoll-4.2.1/cloudoll/template/middlewares/auth.py +0 -31
- cloudoll-4.2.1/cloudoll/template/requirements.txt +0 -1
- cloudoll-4.2.1/tests/integration/test_databases.py +0 -294
- {cloudoll-4.2.1 → cloudoll-4.4.0}/AGENTS.md +0 -0
- {cloudoll-4.2.1 → cloudoll-4.4.0}/AI.md +0 -0
- {cloudoll-4.2.1 → cloudoll-4.4.0}/LICENSE +0 -0
- {cloudoll-4.2.1 → cloudoll-4.4.0}/MANIFEST.in +0 -0
- {cloudoll-4.2.1 → cloudoll-4.4.0}/SECURITY.md +0 -0
- {cloudoll-4.2.1 → cloudoll-4.4.0}/cloudoll/__main__.py +0 -0
- {cloudoll-4.2.1 → cloudoll-4.4.0}/cloudoll/ai/__init__.py +0 -0
- {cloudoll-4.2.1 → cloudoll-4.4.0}/cloudoll/ai/commands.py +0 -0
- {cloudoll-4.2.1 → cloudoll-4.4.0}/cloudoll/ai/docs/app-start.md +0 -0
- {cloudoll-4.2.1 → cloudoll-4.4.0}/cloudoll/ai/docs/deployment.md +0 -0
- {cloudoll-4.2.1 → cloudoll-4.4.0}/cloudoll/ai/docs/event-source.md +0 -0
- {cloudoll-4.2.1 → cloudoll-4.4.0}/cloudoll/ai/docs/exception.md +0 -0
- {cloudoll-4.2.1 → cloudoll-4.4.0}/cloudoll/ai/docs/file-uploads.md +0 -0
- {cloudoll-4.2.1 → cloudoll-4.4.0}/cloudoll/ai/docs/http-client.md +0 -0
- {cloudoll-4.2.1 → cloudoll-4.4.0}/cloudoll/ai/docs/logs.md +0 -0
- {cloudoll-4.2.1 → cloudoll-4.4.0}/cloudoll/ai/docs/middleware.md +0 -0
- {cloudoll-4.2.1 → cloudoll-4.4.0}/cloudoll/ai/docs/migration.md +0 -0
- {cloudoll-4.2.1 → cloudoll-4.4.0}/cloudoll/ai/docs/router.md +0 -0
- {cloudoll-4.2.1 → cloudoll-4.4.0}/cloudoll/ai/docs/structure.md +0 -0
- {cloudoll-4.2.1 → cloudoll-4.4.0}/cloudoll/ai/docs/validation.md +0 -0
- {cloudoll-4.2.1 → cloudoll-4.4.0}/cloudoll/ai/docs/websockets.md +0 -0
- {cloudoll-4.2.1 → cloudoll-4.4.0}/cloudoll/clitool/__init__.py +0 -0
- {cloudoll-4.2.1 → cloudoll-4.4.0}/cloudoll/clitool/m2d.py +0 -0
- {cloudoll-4.2.1 → cloudoll-4.4.0}/cloudoll/clitool/process.py +0 -0
- {cloudoll-4.2.1 → cloudoll-4.4.0}/cloudoll/clitool/schema.py +0 -0
- {cloudoll-4.2.1 → cloudoll-4.4.0}/cloudoll/clitool/spinner.py +0 -0
- {cloudoll-4.2.1 → cloudoll-4.4.0}/cloudoll/logging/__init__.py +0 -0
- {cloudoll-4.2.1 → cloudoll-4.4.0}/cloudoll/mail/__init__.py +0 -0
- {cloudoll-4.2.1 → cloudoll-4.4.0}/cloudoll/observability.py +0 -0
- {cloudoll-4.2.1 → cloudoll-4.4.0}/cloudoll/orm/awsmysql.py +0 -0
- {cloudoll-4.2.1 → cloudoll-4.4.0}/cloudoll/orm/awspostgres.py +0 -0
- {cloudoll-4.2.1 → cloudoll-4.4.0}/cloudoll/orm/base.py +0 -0
- {cloudoll-4.2.1 → cloudoll-4.4.0}/cloudoll/orm/datasources.py +0 -0
- {cloudoll-4.2.1 → cloudoll-4.4.0}/cloudoll/orm/dialects.py +0 -0
- {cloudoll-4.2.1 → cloudoll-4.4.0}/cloudoll/orm/mysql.py +0 -0
- {cloudoll-4.2.1 → cloudoll-4.4.0}/cloudoll/orm/parse.py +0 -0
- {cloudoll-4.2.1 → cloudoll-4.4.0}/cloudoll/orm/postgres.py +0 -0
- {cloudoll-4.2.1 → cloudoll-4.4.0}/cloudoll/orm/streaming.py +0 -0
- {cloudoll-4.2.1 → cloudoll-4.4.0}/cloudoll/orm/test_sql.py +0 -0
- {cloudoll-4.2.1 → cloudoll-4.4.0}/cloudoll/orm/values.py +0 -0
- {cloudoll-4.2.1 → cloudoll-4.4.0}/cloudoll/py.typed +0 -0
- {cloudoll-4.2.1 → cloudoll-4.4.0}/cloudoll/template/__init__.py +0 -0
- {cloudoll-4.2.1 → cloudoll-4.4.0}/cloudoll/template/controllers/admin/test.py +0 -0
- {cloudoll-4.2.1 → cloudoll-4.4.0}/cloudoll/template/controllers/api/index.py +0 -0
- {cloudoll-4.2.1 → cloudoll-4.4.0}/cloudoll/template/controllers/es/es.py +0 -0
- {cloudoll-4.2.1 → cloudoll-4.4.0}/cloudoll/template/controllers/home/index.py +0 -0
- {cloudoll-4.2.1 → cloudoll-4.4.0}/cloudoll/template/controllers/upload/upload.py +0 -0
- {cloudoll-4.2.1 → cloudoll-4.4.0}/cloudoll/template/controllers/ws/ws.py +0 -0
- {cloudoll-4.2.1 → cloudoll-4.4.0}/cloudoll/template/static/css/index.css +0 -0
- {cloudoll-4.2.1 → cloudoll-4.4.0}/cloudoll/template/static/img/cat.avif +0 -0
- {cloudoll-4.2.1 → cloudoll-4.4.0}/cloudoll/template/static/js/index.js +0 -0
- {cloudoll-4.2.1 → cloudoll-4.4.0}/cloudoll/template/templates/index.html +0 -0
- {cloudoll-4.2.1 → cloudoll-4.4.0}/cloudoll/utils/__init__.py +0 -0
- {cloudoll-4.2.1 → cloudoll-4.4.0}/cloudoll/utils/async_tools.py +0 -0
- {cloudoll-4.2.1 → cloudoll-4.4.0}/cloudoll/utils/common.py +0 -0
- {cloudoll-4.2.1 → cloudoll-4.4.0}/cloudoll/utils/password.py +0 -0
- {cloudoll-4.2.1 → cloudoll-4.4.0}/cloudoll/utils/snowflake.py +0 -0
- {cloudoll-4.2.1 → cloudoll-4.4.0}/cloudoll/web/__init__.py +0 -0
- {cloudoll-4.2.1 → cloudoll-4.4.0}/cloudoll/web/context.py +0 -0
- {cloudoll-4.2.1 → cloudoll-4.4.0}/cloudoll/web/exception.py +0 -0
- {cloudoll-4.2.1 → cloudoll-4.4.0}/cloudoll/web/html.py +0 -0
- {cloudoll-4.2.1 → cloudoll-4.4.0}/cloudoll/web/jwt.py +0 -0
- {cloudoll-4.2.1 → cloudoll-4.4.0}/cloudoll/web/lifecycle.py +0 -0
- {cloudoll-4.2.1 → cloudoll-4.4.0}/cloudoll/web/request_data.py +0 -0
- {cloudoll-4.2.1 → cloudoll-4.4.0}/cloudoll/web/requests.py +0 -0
- {cloudoll-4.2.1 → cloudoll-4.4.0}/cloudoll/web/resources.py +0 -0
- {cloudoll-4.2.1 → cloudoll-4.4.0}/cloudoll/web/routing.py +0 -0
- {cloudoll-4.2.1 → cloudoll-4.4.0}/cloudoll/web/settings.py +0 -0
- {cloudoll-4.2.1 → cloudoll-4.4.0}/cloudoll/web/types.py +0 -0
- {cloudoll-4.2.1 → cloudoll-4.4.0}/cloudoll/web/validation.py +0 -0
- {cloudoll-4.2.1 → cloudoll-4.4.0}/cloudoll.egg-info/dependency_links.txt +0 -0
- {cloudoll-4.2.1 → cloudoll-4.4.0}/cloudoll.egg-info/entry_points.txt +0 -0
- {cloudoll-4.2.1 → cloudoll-4.4.0}/cloudoll.egg-info/requires.txt +0 -0
- {cloudoll-4.2.1 → cloudoll-4.4.0}/cloudoll.egg-info/top_level.txt +0 -0
- {cloudoll-4.2.1 → cloudoll-4.4.0}/docs/architecture.md +0 -0
- {cloudoll-4.2.1 → cloudoll-4.4.0}/docs/aurora.md +0 -0
- {cloudoll-4.2.1 → cloudoll-4.4.0}/docs/production.md +0 -0
- {cloudoll-4.2.1 → cloudoll-4.4.0}/docs/reliability.md +0 -0
- {cloudoll-4.2.1 → cloudoll-4.4.0}/docs/schema-generation.md +0 -0
- {cloudoll-4.2.1 → cloudoll-4.4.0}/docs/streaming-and-types.md +0 -0
- {cloudoll-4.2.1 → cloudoll-4.4.0}/scripts/sync_ai_docs.py +0 -0
- {cloudoll-4.2.1 → cloudoll-4.4.0}/setup.cfg +0 -0
- {cloudoll-4.2.1 → cloudoll-4.4.0}/setup.py +0 -0
- {cloudoll-4.2.1 → cloudoll-4.4.0}/tests/audit_dependencies.py +0 -0
- {cloudoll-4.2.1 → cloudoll-4.4.0}/tests/check_release.py +0 -0
- {cloudoll-4.2.1 → cloudoll-4.4.0}/tests/conftest.py +0 -0
- {cloudoll-4.2.1 → cloudoll-4.4.0}/tests/integration/test_aws_failover.py +0 -0
- {cloudoll-4.2.1 → cloudoll-4.4.0}/tests/integration/test_savepoints.py +0 -0
- {cloudoll-4.2.1 → cloudoll-4.4.0}/tests/integration/test_schema.py +0 -0
- {cloudoll-4.2.1 → cloudoll-4.4.0}/tests/integration/test_streaming.py +0 -0
- {cloudoll-4.2.1 → cloudoll-4.4.0}/tests/run_local_databases.py +0 -0
- {cloudoll-4.2.1 → cloudoll-4.4.0}/tests/test_ai.py +0 -0
- {cloudoll-4.2.1 → cloudoll-4.4.0}/tests/test_architecture.py +0 -0
- {cloudoll-4.2.1 → cloudoll-4.4.0}/tests/test_production_contracts.py +0 -0
- {cloudoll-4.2.1 → cloudoll-4.4.0}/tests/test_release_workflow.py +0 -0
- {cloudoll-4.2.1 → cloudoll-4.4.0}/tests/test_retry_and_query_regressions.py +0 -0
- {cloudoll-4.2.1 → cloudoll-4.4.0}/tests/test_review_fixes.py +0 -0
- {cloudoll-4.2.1 → cloudoll-4.4.0}/tests/test_save_snapshots_and_cleanup.py +0 -0
- {cloudoll-4.2.1 → cloudoll-4.4.0}/tests/test_savepoint_unit.py +0 -0
- {cloudoll-4.2.1 → cloudoll-4.4.0}/tests/test_schema_generation.py +0 -0
- {cloudoll-4.2.1 → cloudoll-4.4.0}/tests/test_sql_echo.py +0 -0
- {cloudoll-4.2.1 → cloudoll-4.4.0}/tests/test_startup_logging.py +0 -0
- {cloudoll-4.2.1 → cloudoll-4.4.0}/tests/test_streaming_unit.py +0 -0
- {cloudoll-4.2.1 → cloudoll-4.4.0}/tests/test_typing_regressions.py +0 -0
- {cloudoll-4.2.1 → cloudoll-4.4.0}/tests/test_validation.py +0 -0
- {cloudoll-4.2.1 → cloudoll-4.4.0}/tests/typing/engine_contract.py +0 -0
- {cloudoll-4.2.1 → cloudoll-4.4.0}/tests/typing/field_contract.py +0 -0
- {cloudoll-4.2.1 → cloudoll-4.4.0}/tests/typing/middleware_contract.py +0 -0
- {cloudoll-4.2.1 → cloudoll-4.4.0}/tests/typing/production_contract.py +0 -0
- {cloudoll-4.2.1 → cloudoll-4.4.0}/tests/typing/request_contract.py +0 -0
- {cloudoll-4.2.1 → cloudoll-4.4.0}/tests/typing/web_contract.py +0 -0
|
@@ -0,0 +1,220 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
简体中文见 [CHANGELOG.zh-CN.md](CHANGELOG.zh-CN.md)。
|
|
4
|
+
|
|
5
|
+
## 4.4.0
|
|
6
|
+
|
|
7
|
+
Defect-fix release; backward compatible. Python 3.9+ remains supported.
|
|
8
|
+
|
|
9
|
+
### Database
|
|
10
|
+
|
|
11
|
+
- `for_update()` row locks now require your own transaction. Outside one, the lock
|
|
12
|
+
was released by the commit that `for_update()` issued itself and protected
|
|
13
|
+
nothing; such a call now raises instead of silently doing nothing.
|
|
14
|
+
- A transaction cancelled or timed out while waiting for a connection gives that
|
|
15
|
+
connection back to the pool, so long-running services stop losing connections.
|
|
16
|
+
- Model fields are hashable again: columns can go into sets and serve as dict
|
|
17
|
+
keys (deduplicating columns, excluding groups of fields).
|
|
18
|
+
- `SUM(DISTINCT column)` and similar aggregate deduplication now happens inside
|
|
19
|
+
the aggregate, so values are deduplicated before being combined, and a literal
|
|
20
|
+
inside an aggregate is no longer bound twice.
|
|
21
|
+
- URL query parameters in an AWS datasource string are no longer handed to the
|
|
22
|
+
driver as unknown connection options.
|
|
23
|
+
|
|
24
|
+
### Web and templates
|
|
25
|
+
|
|
26
|
+
- A response that has already started streaming keeps its body when an error
|
|
27
|
+
occurs; the JSON error handler no longer rewrites it. Streaming and SSE
|
|
28
|
+
endpoints stay intact.
|
|
29
|
+
- Page responses no longer repeat `charset` in `Content-Type`.
|
|
30
|
+
- `session` options (`key`, `max_age`, `httponly`, `secure`, `domain`, `path`,
|
|
31
|
+
`samesite`) apply to encrypted cookie, Redis and Memcached storage alike.
|
|
32
|
+
- `render_view()` keywords are `Response` options only, and the template context
|
|
33
|
+
is the positional mapping. A stray keyword now raises `TypeError` instead of
|
|
34
|
+
being silently merged into the context.
|
|
35
|
+
- Development servers bind to 127.0.0.1 by default and no longer occupy
|
|
36
|
+
`port + 1`.
|
|
37
|
+
- `server.ignore_dirs` is honoured for directories such as `logs`, so writing logs
|
|
38
|
+
no longer triggers a reload.
|
|
39
|
+
- The scaffolded authorization middleware now matches its documentation: it is an
|
|
40
|
+
async decorator, lets static paths through, and lets downstream failures reach
|
|
41
|
+
the error layer instead of being flattened into a 500 that echoes the exception
|
|
42
|
+
text.
|
|
43
|
+
|
|
44
|
+
### Command line and new projects
|
|
45
|
+
|
|
46
|
+
- `cloudoll create` no longer copies `__pycache__` and `.pyc` files into the new
|
|
47
|
+
project.
|
|
48
|
+
- The last component of a project name must be letters, digits, underscore, dot
|
|
49
|
+
or dash; names with spaces or shell characters are refused, as is an existing
|
|
50
|
+
target directory.
|
|
51
|
+
- A failed creation exits with a non-zero status and removes the half-written
|
|
52
|
+
project instead of leaving it behind.
|
|
53
|
+
- New projects write independent JWT and session keys to `.env`, which
|
|
54
|
+
`.gitignore` keeps out of version control. Local starts no longer warn about a
|
|
55
|
+
random process-local session key, and logins survive a restart or an added
|
|
56
|
+
worker.
|
|
57
|
+
|
|
58
|
+
### Mail and utilities
|
|
59
|
+
|
|
60
|
+
- Building a `cloudoll.mail.smtp.Client` no longer reaches the network, and one
|
|
61
|
+
client stays usable across sends and server idle timeouts: each `send()` opens
|
|
62
|
+
its own connection, carries one copy of the body, and closes the connection even
|
|
63
|
+
when the send fails.
|
|
64
|
+
- Missing credentials and an empty recipient address now raise a readable error
|
|
65
|
+
before anything is sent.
|
|
66
|
+
- `cloudoll.utils` - reversible encryption, keyed digests, random strings and the
|
|
67
|
+
distributed ID generator - is now official API with a
|
|
68
|
+
[utilities](https://cloudoll.chuchur.com/utils) page and regression tests. None
|
|
69
|
+
of them is a password hash; store user passwords with bcrypt or argon2.
|
|
70
|
+
- New [mail](https://cloudoll.chuchur.com/mail) page documents sending limits
|
|
71
|
+
(SMTPS 465 only, no STARTTLS, no retry or queue). The dead POP3 draft under
|
|
72
|
+
`cloudoll/mail` is gone - Cloudoll does not receive mail.
|
|
73
|
+
|
|
74
|
+
### Upgrade notes
|
|
75
|
+
|
|
76
|
+
- `for_update()` outside a transaction and unexpected `render_view()` keywords now
|
|
77
|
+
raise rather than misbehaving quietly; audit those two call shapes before
|
|
78
|
+
upgrading.
|
|
79
|
+
- `cloudoll create` rejects names it used to accept, such as `my shop`, because
|
|
80
|
+
they reached a shell unsafely.
|
|
81
|
+
- Projects created before this release keep an old `config/conf.local.yaml`
|
|
82
|
+
without a session key; add `session.secret_key` (or set
|
|
83
|
+
`CLOUDOLL_SESSION_SECRET`) so sessions survive restarts and multiple workers.
|
|
84
|
+
- Existing `.env` files need the new `CLOUDOLL_SESSION_SECRET` entry; `.env` has
|
|
85
|
+
always been ignored by the project's `.gitignore`.
|
|
86
|
+
|
|
87
|
+
### Documentation
|
|
88
|
+
|
|
89
|
+
- JWT middleware examples use `web.RequestKey` instead of a plain string key, so
|
|
90
|
+
aiohttp stops warning about it.
|
|
91
|
+
- The quick start and session pages describe how a new project injects its keys.
|
|
92
|
+
|
|
93
|
+
## 4.3.0
|
|
94
|
+
|
|
95
|
+
### ORM queries and writes
|
|
96
|
+
|
|
97
|
+
- Add explicit LEFT/INNER/RIGHT JOIN kinds, query-level DISTINCT, `one_dict()`
|
|
98
|
+
for projected/aggregate rows, and non-consuming `exists()` checks.
|
|
99
|
+
- Add parameterized scalar/IN and EXISTS/NOT EXISTS subqueries with snapshot
|
|
100
|
+
semantics and datasource/dialect compatibility checks.
|
|
101
|
+
- Add read-only table aliases for self-joins, non-recursive CTEs, and
|
|
102
|
+
UNION/UNION ALL with branch-local and outer pagination semantics.
|
|
103
|
+
- Add atomic expression-valued updates and transaction-owned `for_update()`
|
|
104
|
+
row locks, including mutually exclusive NOWAIT and SKIP LOCKED options.
|
|
105
|
+
- Add single-statement `upsert()` with explicit update fields; PostgreSQL
|
|
106
|
+
supports conflict targets, while MySQL explicitly rejects that option.
|
|
107
|
+
- Export `Relation` and `Subquery` types. Reject writes against aliases,
|
|
108
|
+
CTE/UNION sources and joined queries rather than silently ignoring sources.
|
|
109
|
+
|
|
110
|
+
### Documentation and verification
|
|
111
|
+
|
|
112
|
+
- Expand grouping/HAVING, aggregates, default datasource usage and query
|
|
113
|
+
result contracts. Normal application CRUD defaults to entity APIs without
|
|
114
|
+
unnecessary `.use(db)` or handwritten SQL.
|
|
115
|
+
- Update bundled AI guidance and version-matched examples, including locking,
|
|
116
|
+
unique constraints, snapshots and unsupported advanced combinations.
|
|
117
|
+
- Add MySQL 8.4/PostgreSQL 16 integration coverage for query sources, upserts,
|
|
118
|
+
concurrency, rollback and row-lock contention. Aurora remains unverified.
|
|
119
|
+
|
|
120
|
+
## 4.2.1
|
|
121
|
+
|
|
122
|
+
- Correct the AI initialization regression test to compare the original bytes
|
|
123
|
+
rather than assume LF newlines on Windows. Keep preservation and idempotence
|
|
124
|
+
assertions enabled on every platform.
|
|
125
|
+
- Normalize the generated full documentation's trailing newline.
|
|
126
|
+
- Include all 4.2.0 features. The 4.2.0 tag was blocked by Windows CI and was
|
|
127
|
+
not published to PyPI; 4.2.1 is the replacement release.
|
|
128
|
+
|
|
129
|
+
## 4.2.0
|
|
130
|
+
|
|
131
|
+
Backward-compatible AI-assisted development release. Python 3.9+ remains supported.
|
|
132
|
+
|
|
133
|
+
- Add offline `cloudoll ai list`, `read`, and `search` commands for bundled official
|
|
134
|
+
documentation, with source URLs, version metadata and content integrity checks.
|
|
135
|
+
- Add `cloudoll ai init` for existing projects. New scaffolds automatically include
|
|
136
|
+
an AGENTS.md entry and a project-local Cloudoll skill covering documented project
|
|
137
|
+
structure, validation, ORM, resource lifecycle, security and verification.
|
|
138
|
+
- Preserve existing project instructions and refuse to overwrite customized skills
|
|
139
|
+
or write through symbolic links. Initialization is repeatable.
|
|
140
|
+
- Add documentation synchronization tooling and website LLM discovery assets.
|
|
141
|
+
Test both instruction initialization and AI resources in the built wheel.
|
|
142
|
+
|
|
143
|
+
## 4.1.0
|
|
144
|
+
|
|
145
|
+
Backward-compatible feature release. Pydantic 2 (`>=2.0,<3`) is now a core
|
|
146
|
+
runtime dependency. Existing handlers and explicit ORM engine bindings remain
|
|
147
|
+
supported. Python 3.9+ remains supported by the CI matrix.
|
|
148
|
+
|
|
149
|
+
- Correct lifecycle callback and JWT payload type declarations for strict
|
|
150
|
+
checking with current dependency annotations.
|
|
151
|
+
- Include HTTP method and actual request path in exception logs; emit 4xx access
|
|
152
|
+
logs at WARNING and 5xx at ERROR so failed requests remain visible above INFO.
|
|
153
|
+
|
|
154
|
+
- Add Pydantic 2 request validation with typed `Body`, `Query`, `Form`, and
|
|
155
|
+
`Path` bindings, repeated collection parameters and structured HTTP 400 errors.
|
|
156
|
+
Preserve legacy request and streaming multipart handlers.
|
|
157
|
+
|
|
158
|
+
- Add application-local named ORM datasources via `orm.default` and model
|
|
159
|
+
`__datasource__`, independent class-level queries, `Model.query()` and
|
|
160
|
+
`Model.transaction()`. Reuse existing task-owned engine transactions.
|
|
161
|
+
- Add `datasource_context` for scoped standalone/test engine bindings. Keep
|
|
162
|
+
explicit `.use(engine)`, offline SQL compilation and bound records compatible.
|
|
163
|
+
|
|
164
|
+
## 4.0.0
|
|
165
|
+
|
|
166
|
+
This release contains breaking changes to configuration, security, ORM and the
|
|
167
|
+
application lifecycle. Read the migration guide before upgrading.
|
|
168
|
+
|
|
169
|
+
### Breaking changes and migration
|
|
170
|
+
|
|
171
|
+
- Python 3.9+ is required; database/cache drivers are optional extras.
|
|
172
|
+
- Configuration values no longer execute Python expressions. Supply literal
|
|
173
|
+
numeric values and inject required environment variables explicitly.
|
|
174
|
+
- `Model.use()` returns an independent Query. Records use UNSET and dirty-field
|
|
175
|
+
snapshots; successful outer commits update the saved baseline. Database errors
|
|
176
|
+
propagate instead of appearing as empty results.
|
|
177
|
+
- PostgreSQL ORM inserts use RETURNING. Raw inserts without RETURNING and batch
|
|
178
|
+
inserts do not manufacture a primary key.
|
|
179
|
+
- Sessions require a private, stable key for multi-worker/restart persistence;
|
|
180
|
+
discard cookies created with old publicly derivable keys.
|
|
181
|
+
- Middleware uses the direct async decorator contract. Application creation is
|
|
182
|
+
instance-local and may only be performed once per instance.
|
|
183
|
+
- CLI service identity includes process creation time and command line. Unknown
|
|
184
|
+
legacy PID identities are not killed automatically; stop old services safely
|
|
185
|
+
before upgrading. Production mode remains foreground, not a process supervisor.
|
|
186
|
+
|
|
187
|
+
### ORM and developer experience
|
|
188
|
+
|
|
189
|
+
- Added native MySQL/PostgreSQL transactions, nested savepoints, scoped streaming,
|
|
190
|
+
generic Query/Field typing and dialect-specific schema generation.
|
|
191
|
+
- Added opt-in SQL/parameter echo, connection/query/cleanup timeouts, and safe
|
|
192
|
+
cancellation. Writes and uncertain commits are never automatically replayed.
|
|
193
|
+
- Added isolated route/module discovery and explicit application components.
|
|
194
|
+
- Development children and reloads create a fresh Application at the explicit
|
|
195
|
+
project root instead of inheriting a parent's cached app/context through fork.
|
|
196
|
+
- Scaffold dependencies now target Cloudoll 4.0.0; scaffold business code remains
|
|
197
|
+
illustrative, not a complete application authorization system.
|
|
198
|
+
|
|
199
|
+
### Core production hardening
|
|
200
|
+
|
|
201
|
+
- Explicitly selected missing configuration files now raise `FileNotFoundError`.
|
|
202
|
+
Use `Application.create(env=None)` or `config={}` for intentional no-config mode.
|
|
203
|
+
- Library-owned configuration types/ranges are validated before startup and after
|
|
204
|
+
`on_create`. Custom business/plugin keys remain supported.
|
|
205
|
+
- JWT verification requires `exp` by default and supports issuer, audience,
|
|
206
|
+
leeway and required claims. Invalid tokens return `None`; configuration errors
|
|
207
|
+
raise. Explicit `require=()` is the legacy-token escape hatch.
|
|
208
|
+
- Native pool close and application resource cleanup have finite deadlines.
|
|
209
|
+
- Added JSON logging, structured-data masking, string-redaction extension,
|
|
210
|
+
trace correlation and value-free HTTP/native query observation events.
|
|
211
|
+
- Added native deadlock/commit-cancellation regression tests and dependency audit CI.
|
|
212
|
+
|
|
213
|
+
### Migration
|
|
214
|
+
|
|
215
|
+
See [reliability](docs/reliability.md) for the existing transaction, savepoint,
|
|
216
|
+
UNSET/dirty-field, CLI/PID, SQL echo and request parsing changes. See
|
|
217
|
+
[production contracts](docs/production.md) for the new configuration and APIs.
|
|
218
|
+
|
|
219
|
+
Aurora transactions and connection reuse are implemented but remain untested.
|
|
220
|
+
Native driver validation must not be presented as Aurora failover validation.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: cloudoll
|
|
3
|
-
Version: 4.
|
|
3
|
+
Version: 4.4.0
|
|
4
4
|
Summary: Assist in quickly creating distributable microservices based on aiohttp, with a focus on simplicity and ease of use.
|
|
5
5
|
Author-email: Qiu <smallerqiu@gmail.com>
|
|
6
6
|
License-Expression: MIT
|
|
@@ -54,7 +54,7 @@ Dynamic: license-file
|
|
|
54
54
|
|
|
55
55
|
English | [简体中文](README.zh-CN.md)
|
|
56
56
|
|
|
57
|
-
Cloudoll 4.
|
|
57
|
+
Cloudoll 4.4.0 is an aiohttp-based Python library for routing, middleware,
|
|
58
58
|
templates, sessions, JWT, database access and application scaffolding.
|
|
59
59
|
|
|
60
60
|
## AI-assisted development
|
|
@@ -71,8 +71,8 @@ does not have `cloudoll ai --help`, consult its matching README and source first
|
|
|
71
71
|
Python 3.9+ is required. Install only the optional drivers you use:
|
|
72
72
|
|
|
73
73
|
```sh
|
|
74
|
-
python -m pip install 'cloudoll==4.
|
|
75
|
-
python -m pip install 'cloudoll[mysql,postgres,cache]==4.
|
|
74
|
+
python -m pip install 'cloudoll==4.4.0'
|
|
75
|
+
python -m pip install 'cloudoll[mysql,postgres,cache]==4.4.0'
|
|
76
76
|
```
|
|
77
77
|
|
|
78
78
|
The AWS extra requires Python 3.10+. Aurora remains untested; see
|
|
@@ -87,7 +87,8 @@ python -m pip install -r requirements.txt
|
|
|
87
87
|
cloudoll start -n myapp
|
|
88
88
|
```
|
|
89
89
|
|
|
90
|
-
The generated project targets 4.
|
|
90
|
+
The generated project targets 4.4.0 and receives random JWT and session secrets
|
|
91
|
+
in `.env`. Controllers
|
|
91
92
|
and authentication middleware are examples: replace demo credentials and supply
|
|
92
93
|
your own authorization and upload policies before deployment.
|
|
93
94
|
|
|
@@ -172,8 +173,8 @@ python -m ruff check cloudoll tests
|
|
|
172
173
|
python -m mypy
|
|
173
174
|
python -m pytest -q -m 'not integration' -k 'not aws'
|
|
174
175
|
python -m build
|
|
175
|
-
python tests/check_wheel.py dist/cloudoll-4.
|
|
176
|
-
python tests/check_release.py dist/cloudoll-4.
|
|
176
|
+
python tests/check_wheel.py dist/cloudoll-4.4.0-py3-none-any.whl
|
|
177
|
+
python tests/check_release.py dist/cloudoll-4.4.0-py3-none-any.whl
|
|
177
178
|
```
|
|
178
179
|
|
|
179
180
|
Native integration tests require explicitly configured disposable databases.
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
English | [简体中文](README.zh-CN.md)
|
|
4
4
|
|
|
5
|
-
Cloudoll 4.
|
|
5
|
+
Cloudoll 4.4.0 is an aiohttp-based Python library for routing, middleware,
|
|
6
6
|
templates, sessions, JWT, database access and application scaffolding.
|
|
7
7
|
|
|
8
8
|
## AI-assisted development
|
|
@@ -19,8 +19,8 @@ does not have `cloudoll ai --help`, consult its matching README and source first
|
|
|
19
19
|
Python 3.9+ is required. Install only the optional drivers you use:
|
|
20
20
|
|
|
21
21
|
```sh
|
|
22
|
-
python -m pip install 'cloudoll==4.
|
|
23
|
-
python -m pip install 'cloudoll[mysql,postgres,cache]==4.
|
|
22
|
+
python -m pip install 'cloudoll==4.4.0'
|
|
23
|
+
python -m pip install 'cloudoll[mysql,postgres,cache]==4.4.0'
|
|
24
24
|
```
|
|
25
25
|
|
|
26
26
|
The AWS extra requires Python 3.10+. Aurora remains untested; see
|
|
@@ -35,7 +35,8 @@ python -m pip install -r requirements.txt
|
|
|
35
35
|
cloudoll start -n myapp
|
|
36
36
|
```
|
|
37
37
|
|
|
38
|
-
The generated project targets 4.
|
|
38
|
+
The generated project targets 4.4.0 and receives random JWT and session secrets
|
|
39
|
+
in `.env`. Controllers
|
|
39
40
|
and authentication middleware are examples: replace demo credentials and supply
|
|
40
41
|
your own authorization and upload policies before deployment.
|
|
41
42
|
|
|
@@ -120,8 +121,8 @@ python -m ruff check cloudoll tests
|
|
|
120
121
|
python -m mypy
|
|
121
122
|
python -m pytest -q -m 'not integration' -k 'not aws'
|
|
122
123
|
python -m build
|
|
123
|
-
python tests/check_wheel.py dist/cloudoll-4.
|
|
124
|
-
python tests/check_release.py dist/cloudoll-4.
|
|
124
|
+
python tests/check_wheel.py dist/cloudoll-4.4.0-py3-none-any.whl
|
|
125
|
+
python tests/check_release.py dist/cloudoll-4.4.0-py3-none-any.whl
|
|
125
126
|
```
|
|
126
127
|
|
|
127
128
|
Native integration tests require explicitly configured disposable databases.
|
|
@@ -2,11 +2,11 @@
|
|
|
2
2
|
|
|
3
3
|
[English](README.md) | 简体中文
|
|
4
4
|
|
|
5
|
-
生产配置、资源关闭期限、JWT 验证、JSON 日志与监控接入见 [生产运行契约](docs/production.md);版本兼容及发布检查见 [维护政策](docs/maintenance.md),安全问题报告见 [SECURITY.md](SECURITY.md)。
|
|
5
|
+
生产配置、资源关闭期限、JWT 验证、JSON 日志与监控接入见 [生产运行契约](docs/production.md);版本兼容及发布检查见 [维护政策](docs/maintenance.md);各版本变化见 [更新日志](CHANGELOG.zh-CN.md),安全问题报告见 [SECURITY.md](SECURITY.md)。
|
|
6
6
|
|
|
7
7
|
Cloudoll 是一个基于 aiohttp 的 Python Web 开发库,提供路由自动注册、中间件、模板渲染、会话管理、JWT、数据库访问及命令行脚手架,帮助快速构建 Web 应用和微服务。
|
|
8
8
|
|
|
9
|
-
本文适用于 Cloudoll 4.
|
|
9
|
+
本文适用于 Cloudoll 4.4.0。从 3.x 升级前请阅读下方迁移说明。
|
|
10
10
|
|
|
11
11
|
## AI 辅助开发
|
|
12
12
|
|
|
@@ -25,10 +25,10 @@ Cloudoll 是一个基于 aiohttp 的 Python Web 开发库,提供路由自动
|
|
|
25
25
|
|
|
26
26
|
## 安装
|
|
27
27
|
|
|
28
|
-
安装 4.
|
|
28
|
+
安装 4.4.0:
|
|
29
29
|
|
|
30
30
|
```sh
|
|
31
|
-
python -m pip install 'cloudoll==4.
|
|
31
|
+
python -m pip install 'cloudoll==4.4.0'
|
|
32
32
|
```
|
|
33
33
|
|
|
34
34
|
在当前仓库目录安装源码:
|
|
@@ -41,16 +41,16 @@ python -m pip install -e .
|
|
|
41
41
|
|
|
42
42
|
```sh
|
|
43
43
|
# MySQL
|
|
44
|
-
python -m pip install 'cloudoll[mysql]==4.
|
|
44
|
+
python -m pip install 'cloudoll[mysql]==4.4.0'
|
|
45
45
|
|
|
46
46
|
# PostgreSQL
|
|
47
|
-
python -m pip install 'cloudoll[postgres]==4.
|
|
47
|
+
python -m pip install 'cloudoll[postgres]==4.4.0'
|
|
48
48
|
|
|
49
49
|
# AWS 数据库驱动
|
|
50
|
-
python -m pip install 'cloudoll[aws]==4.
|
|
50
|
+
python -m pip install 'cloudoll[aws]==4.4.0'
|
|
51
51
|
|
|
52
52
|
# Redis / Memcached 会话或 Redis 数据库
|
|
53
|
-
python -m pip install 'cloudoll[cache]==4.
|
|
53
|
+
python -m pip install 'cloudoll[cache]==4.4.0'
|
|
54
54
|
```
|
|
55
55
|
|
|
56
56
|
源码开发时可用 `python -m pip install -e '.[mysql,postgres,cache,dev]'` 安装。
|
|
@@ -89,7 +89,7 @@ myapp/
|
|
|
89
89
|
└── templates/
|
|
90
90
|
```
|
|
91
91
|
|
|
92
|
-
|
|
92
|
+
脚手架中的鉴权中间件和登录接口用于演示。正式使用前,应替换示例账号、密码和业务鉴权逻辑。新建项目会在 `.env` 里获得相互独立的 JWT 与 Session 密钥。
|
|
93
93
|
|
|
94
94
|
### 手动创建应用
|
|
95
95
|
|
|
@@ -546,8 +546,8 @@ cloudoll restart -n myapp
|
|
|
546
546
|
python -m pip install -e '.[mysql,postgres,cache,dev]'
|
|
547
547
|
python -m pytest -q -m 'not integration' -k 'not aws'
|
|
548
548
|
python -m build
|
|
549
|
-
python tests/check_wheel.py dist/cloudoll-4.
|
|
550
|
-
python tests/check_release.py dist/cloudoll-4.
|
|
549
|
+
python tests/check_wheel.py dist/cloudoll-4.4.0-py3-none-any.whl
|
|
550
|
+
python tests/check_release.py dist/cloudoll-4.4.0-py3-none-any.whl
|
|
551
551
|
```
|
|
552
552
|
|
|
553
553
|
最后一条命令用于验证构建出的 wheel,版本号变化后请调整文件名。测试使用模拟数据库连接及本机 HTTP 服务;真实数据库连接和 AWS 故障切换需要单独的集成环境。
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "4.4.0"
|
|
@@ -5,3 +5,7 @@ Before building or changing a Cloudoll application, read `.agents/skills/cloudol
|
|
|
5
5
|
Official documentation is bundled with the installed library: `python -m cloudoll.cli ai list`, `ai read <topic>`, and `ai search <query>`. These commands work offline without MCP. Read `structure`, `config`, `router`, and `validation` before designing an application; read `database` before database work. Consult the installed source when resolving a signature discrepancy; report the discrepancy rather than inventing an API.
|
|
6
6
|
|
|
7
7
|
Prefer the documented scaffold, auto-discovered controllers/middlewares, YAML configuration, framework-owned database lifecycle, typed request validation, and ORM for ordinary CRUD. Low-level alternatives require a task-specific reason. Never silently replace Cloudoll's architecture with patterns from another framework.
|
|
8
|
+
|
|
9
|
+
Ordinary CRUD, joins, filters, aliases, counts and pagination use entity/Query APIs. With initialized application datasources and `orm.default`, omit `.use(db)` in routes and services; explicit binding is for intentional overrides or context-free scripts/tests. Before using raw SQL, verify and state the specific ORM capability gap, not merely that the query contains JOIN or COUNT.
|
|
10
|
+
|
|
11
|
+
Grouping, HAVING and aggregate expressions are also supported. Consult the installed database topic for the full capability inventory; 4.3.0 additions must not be assumed available in an older installed release.
|
|
@@ -49,6 +49,8 @@ python -m cloudoll.cli ai search transaction
|
|
|
49
49
|
.agents/skills/cloudoll/SKILL.md,再通过 cloudoll ai read 查阅相关文档。
|
|
50
50
|
新项目遵循自动发现的 controllers/middlewares、YAML 配置、框架管理的
|
|
51
51
|
数据库生命周期、类型化参数校验和 ORM。若需要偏离默认方案,先说明理由。
|
|
52
|
+
普通 CRUD、联表、筛选、计数和分页用实体 API;配置 orm.default 后,
|
|
53
|
+
应用代码默认省略 .use(db)。原始 SQL 须先确认并说明当前 ORM 的具体能力缺口。
|
|
52
54
|
完成后说明查阅的主题、测试结果和未验证的部分。
|
|
53
55
|
```
|
|
54
56
|
|
|
@@ -6,10 +6,74 @@ icon: logs
|
|
|
6
6
|
|
|
7
7
|
# 更新日志
|
|
8
8
|
|
|
9
|
-
按版本倒序记录 Cloudoll 的主要变化。当前使用方法请以本站 4.
|
|
9
|
+
按版本倒序记录 Cloudoll 的主要变化。当前使用方法请以本站 4.4.0 文档为准,历史功能不代表当前仍保留相同 API。
|
|
10
10
|
|
|
11
11
|
历史版本日期为对应源码提交日期。各版本源码可通过表格中的链接查看。
|
|
12
12
|
|
|
13
|
+
## 4.4.0
|
|
14
|
+
|
|
15
|
+
缺陷修复版本,向后兼容;Python 3.9+ 仍然支持。
|
|
16
|
+
|
|
17
|
+
### 数据库
|
|
18
|
+
|
|
19
|
+
- `for_update()` 行锁必须在调用方自己的事务里使用。以前脱离事务的写法会临时开一个事务,锁随提交立刻释放,实际什么都没锁住;现在这样的调用直接报错。
|
|
20
|
+
- 开启事务时获取连接超时或被取消,已借到的连接会归还连接池,服务跑久了不再慢慢耗光连接。
|
|
21
|
+
- 模型字段恢复可哈希,可以放进 `set` 或作为字典键(列去重、批量排除字段)。
|
|
22
|
+
- `SUM(DISTINCT column)` 等聚合去重编译到聚合函数内部,去重发生在求和之前;聚合里的字面量不再被重复绑定参数。
|
|
23
|
+
- AWS 数据源串里的 URL 查询参数不再作为未知参数传给驱动。
|
|
24
|
+
|
|
25
|
+
### Web 与模板
|
|
26
|
+
|
|
27
|
+
- 已经开始输出的响应不再被 JSON 错误处理改写坏,流式与 SSE 接口出错时保留原响应。
|
|
28
|
+
- 页面响应的 `Content-Type` 不再出现两个 `charset`。
|
|
29
|
+
- `session` 的 `key`、`max_age`、`httponly`、`secure`、`domain`、`path`、`samesite` 在加密 Cookie、Redis、Memcached 三种存储下都生效。
|
|
30
|
+
- `render_view()` 的关键字参数只归一处:模板上下文按位置传字典,关键字参数一律是 `Response` 选项,传错直接抛 `TypeError`,不再被当成上下文吞掉。
|
|
31
|
+
- 默认监听 127.0.0.1,开发模式不再额外占用配置端口 +1。
|
|
32
|
+
- `server.ignore_dirs` 对 `logs` 等目录生效,写日志不再触发热重载。
|
|
33
|
+
- 脚手架的鉴权中间件示例与文档一致:async 装饰器写法,放行静态资源,不再把后续处理器的异常吞成带错误文本的 500。
|
|
34
|
+
|
|
35
|
+
### 命令行与新建项目
|
|
36
|
+
|
|
37
|
+
- `cloudoll create` 不再把 `__pycache__`、`.pyc` 复制进新项目。
|
|
38
|
+
- 项目名最后一段只能是字母、数字、下划线、点、短横线;带空格或 shell 元字符的名字被拒绝,已存在的目标目录也会报错。
|
|
39
|
+
- 创建失败时退出码非 0,并回收只写了一半的目录,不会留下半个项目。
|
|
40
|
+
- 新项目在 `.env` 里同时生成 JWT 与 Session 两把独立密钥,配置读取环境变量,`.gitignore` 忽略 `.env`。本地启动不再出现“使用随机进程本地密钥”的告警,重启和多 worker 之间登录状态不再丢失。
|
|
41
|
+
|
|
42
|
+
### 邮件与工具函数
|
|
43
|
+
|
|
44
|
+
- 邮件客户端构造时不再立刻联网,发送过一次或服务器空闲断开后仍能继续使用:每次 `send()` 自建连接、只带一份正文,失败时也会关闭连接。
|
|
45
|
+
- 缺少账号或授权码、收件人为空时立即给出可读错误,不再留给服务器报认证失败。
|
|
46
|
+
- `cloudoll.utils` 的可逆加密、单向摘要、随机字符串、分布式 ID 成为正式 API,见[工具函数](/utils)。存用户密码请改用 bcrypt/argon2,这些工具都不是口令哈希。
|
|
47
|
+
- 新增[发送邮件](/mail)页;`cloudoll/mail` 下从未生效的 POP3 草稿文件被移除,库本身不提供收信能力。
|
|
48
|
+
|
|
49
|
+
### 升级提示
|
|
50
|
+
|
|
51
|
+
- 在事务外调用 `for_update()`、给 `render_view()` 传多余关键字,以前是静默出错,现在会抛异常;升级前先检查这两类调用。
|
|
52
|
+
- `cloudoll create` 开始拒绝带空格和 shell 元字符的项目名。
|
|
53
|
+
- 老项目请自行补上 `session.secret_key` 或 `CLOUDOLL_SESSION_SECRET`,否则重启、多 worker 之间仍会丢登录状态。
|
|
54
|
+
|
|
55
|
+
### 文档
|
|
56
|
+
|
|
57
|
+
- JWT 中间件示例改用 `web.RequestKey`,避免 aiohttp 的字符串键告警。
|
|
58
|
+
- [快速开始](/)与 [Cookie 与 Session](/session-cookie)说明新项目的密钥注入方式。
|
|
59
|
+
|
|
60
|
+
## 4.3.0
|
|
61
|
+
|
|
62
|
+
### ORM 查询与写入
|
|
63
|
+
|
|
64
|
+
- JOIN 新增显式 LEFT/INNER/RIGHT 类型,默认保持 LEFT;增加查询级 `distinct()`、保留聚合与别名列的 `one_dict()`、不消费查询的 `exists()`。
|
|
65
|
+
- 新增参数化 IN、标量、EXISTS/NOT EXISTS 子查询,创建时快照 SQL 与参数,并校验数据源和方言。
|
|
66
|
+
- 新增 `Model.alias()` 表别名和自连接、非递归 CTE、UNION/UNION ALL;区分分支分页与合并结果分页,保留正确计数语义。
|
|
67
|
+
- 新增表达式原子更新和 `for_update()` 行锁,支持 NOWAIT、SKIP LOCKED;事务由调用方管理,不自动重试。
|
|
68
|
+
- 新增单条原子 `upsert()`,显式指定更新列;PostgreSQL 支持冲突目标,MySQL 明确拒绝不能实现的冲突目标选项。
|
|
69
|
+
- 导出 `Relation`、`Subquery` 类型;明确拒绝别名、CTE、UNION 和 JOIN 查询的直接写入,避免静默忽略查询源。
|
|
70
|
+
|
|
71
|
+
### 文档与验证
|
|
72
|
+
|
|
73
|
+
- 补齐 GROUP BY、HAVING、聚合、返回类型和默认数据源示例;普通应用 CRUD 优先实体 API,不必重复 `.use(db)`。
|
|
74
|
+
- 同步 AI 指引与随包文档,说明行锁、唯一约束、版本适用范围和高级查询限制。
|
|
75
|
+
- 增加 MySQL 8.4 / PostgreSQL 16 真实数据库测试,覆盖并发 upsert、回滚、锁竞争、CTE 和 UNION。Aurora 仍未经过真实环境验证。
|
|
76
|
+
|
|
13
77
|
## 4.2.1
|
|
14
78
|
|
|
15
79
|
- 修正 AI 初始化测试对 Windows CRLF 换行的错误假设,继续验证原有内容保留和重复初始化不变。
|
|
@@ -26,8 +90,6 @@ icon: logs
|
|
|
26
90
|
|
|
27
91
|
## 4.1.0
|
|
28
92
|
|
|
29
|
-
本节对应 4.1.0 源码变更;实际发布状态以 PyPI 为准。
|
|
30
|
-
|
|
31
93
|
- [默认数据源](/database#默认数据源与模型绑定):orm.default、模型 __datasource__、独立类级查询、query() 与 transaction(),保留显式 use(engine)。
|
|
32
94
|
- datasource_context 为独立任务和测试提供作用域绑定;事务复用现有引擎机制,应用与并发任务保持隔离。
|
|
33
95
|
- [请求参数校验](/validation):Pydantic 2 支持 Body、Query、Form、Path,重复数组参数和结构化 HTTP 400,兼容旧接口与流式上传。
|
|
@@ -14,9 +14,21 @@ CLI 默认读取项目根目录的 `config/conf.local.yaml`。选择生产配置
|
|
|
14
14
|
cloudoll start -n myapp -env prod -m production
|
|
15
15
|
```
|
|
16
16
|
|
|
17
|
-
`-env prod` 选择文件,`-m production` 选择运行模式,两者不是同一个开关。通过 `--host` / `--port`
|
|
17
|
+
`-env prod` 选择文件,`-m production` 选择运行模式,两者不是同一个开关。通过 `--host` / `--port` 可覆盖监听地址;未传入时使用配置。配置也缺省时,监听地址为本机回环 `127.0.0.1`、端口 `9001`;需要对外提供服务时显式写入 `server.host: 0.0.0.0` 或使用 `--host 0.0.0.0`。开发模式只有工作进程监听业务端口,监督进程不占用其他端口。入口参数 `-e app` 是模块名,不是 `app.py`。
|
|
18
18
|
|
|
19
|
-
配置必须是 YAML 映射;加载时使用安全 YAML
|
|
19
|
+
配置必须是 YAML 映射;加载时使用安全 YAML 解析,并通过 EnvYAML 严格展开环境变量。默认情况下,缺少引用的环境变量会报错。
|
|
20
|
+
|
|
21
|
+
### `.env` 文件
|
|
22
|
+
|
|
23
|
+
EnvYAML 会自动读取当前工作目录下的 `.env`。从项目根目录启动时,可将配置中引用的变量放在根目录的 `.env` 中,也可以由 shell、容器或进程管理器注入。
|
|
24
|
+
|
|
25
|
+
- 可通过进程环境变量 `ENV_FILE` 指定其他文件;从不同目录启动时,建议使用绝对路径。
|
|
26
|
+
- 默认 `.env` 路径相对于当前工作目录,不是 YAML 所在目录;`get_config(..., root=...)` 只指定 YAML 配置的根目录,不改变 `.env` 的查找位置。
|
|
27
|
+
- 当前 EnvYAML 实现中,文件中的变量会覆盖同名进程环境变量,再用于 YAML 占位符展开。生产环境应避免残留本地 `.env` 覆盖部署配置。
|
|
28
|
+
- 文件变量仅进入 EnvYAML 配置,不会写入 `os.environ`;直接使用 `os.getenv()` 或 `os.environ` 的业务代码不能因此读到这些变量。
|
|
29
|
+
- `-env prod` 选择 `config/conf.prod.yaml`,不会自动切换为 `.env.prod`;需要时通过 `ENV_FILE` 指定。
|
|
30
|
+
|
|
31
|
+
不要提交包含密码或密钥的 `.env`;可提交仅包含变量名和占位值的 `.env.example`。
|
|
20
32
|
|
|
21
33
|
显式指定的配置文件不存在会抛 FileNotFoundError,不再返回空配置继续启动。核心配置节、端口/请求大小、布尔开关、资源关闭期限和 JWT 策略会在应用创建时校验,on_create 修改后再次校验。业务自定义键仍可使用;数据库驱动参数由相应引擎校验。
|
|
22
34
|
|
|
@@ -78,9 +78,14 @@ session:
|
|
|
78
78
|
max_age: 86400
|
|
79
79
|
httponly: true
|
|
80
80
|
secure: false
|
|
81
|
+
domain: .example.com
|
|
82
|
+
path: /
|
|
83
|
+
samesite: Lax
|
|
81
84
|
```
|
|
82
85
|
|
|
83
|
-
|
|
86
|
+
`domain`、`path`、`samesite` 属于 Session Cookie 本身,Cookie、Redis、Memcached 三种存储都读取同一份配置;Redis 存储下不要把这三个键写进 `redis` 子配置。`samesite` 只接受 `Strict`、`Lax`、`None`;`None` 表示不下发该属性,使用浏览器默认策略。`path` 决定浏览器在哪些路径回传 Session Cookie,改成子路径后原路径下的请求将不再带会话。HTTPS 生产环境使用 `secure: true`,此时 `samesite: None` 还要求浏览器允许跨站发送,仅在确有跨站回调时使用。
|
|
87
|
+
|
|
88
|
+
`cloudoll create` 生成的项目已在 `config/conf.local.yaml` 写好 `session.secret_key: $CLOUDOLL_SESSION_SECRET`,并把随机密钥连同 JWT 密钥一起写入项目根目录的 `.env`,开箱即用、重启不掉线;`.env` 已被 `.gitignore` 忽略,生产环境改用环境变量注入同名变量。也可只在进程环境设置 CLOUDOLL_SESSION_SECRET。两处都没有时框架生成应用进程本地随机密钥并记录一次告警,重启会使旧 Session 失效,多进程间也不能共享;生产必须使用一致的随机密钥。更换密钥会使原 Cookie 失效。
|
|
84
89
|
|
|
85
90
|
Cookie 容量有限,不要保存大对象、密码或完整业务数据。客户端加密 Cookie 模式无法仅靠退出操作撤销其他地方留存的旧 Cookie;需要集中撤销时使用服务端存储及业务级会话控制。
|
|
86
91
|
|