Compare commits

..
Author SHA1 Message Date
Typosaurus 63366bb240 ticket #93 attempt 1
DevPlace CI / test (pull_request) Failing after 11s
2026-07-23 02:03:12 +00:00
Typosaurus a55d12696a ticket #93 attempt 1 2026-07-23 01:33:37 +00:00
7 changed files with 7 additions and 21 deletions
File diff suppressed because one or more lines are too long
-5
View File
@@ -12,7 +12,6 @@ from fastapi import FastAPI, Request
from fastapi.responses import HTMLResponse, RedirectResponse from fastapi.responses import HTMLResponse, RedirectResponse
from fastapi.staticfiles import StaticFiles from fastapi.staticfiles import StaticFiles
from fastapi.exceptions import RequestValidationError from fastapi.exceptions import RequestValidationError
from starlette.middleware.gzip import GZipMiddleware
from devplacepy.config import ( from devplacepy.config import (
STATIC_DIR, STATIC_DIR,
STATIC_VERSION, STATIC_VERSION,
@@ -610,10 +609,6 @@ async def response_timing(request: Request, call_next):
response.headers["X-Response-Time"] = f"{(time.perf_counter() - start) * 1000:.1f}ms" response.headers["X-Response-Time"] = f"{(time.perf_counter() - start) * 1000:.1f}ms"
return response return response
app.add_middleware(GZipMiddleware, minimum_size=512, compresslevel=5)
_home_cache = TTLCache(ttl=int(os.environ.get("DEVPLACE_HOME_CACHE_TTL", "60")), max_size=4) _home_cache = TTLCache(ttl=int(os.environ.get("DEVPLACE_HOME_CACHE_TTL", "60")), max_size=4)
+2 -2
View File
@@ -439,8 +439,8 @@ class VoteForm(BaseModel):
@field_validator("value") @field_validator("value")
@classmethod @classmethod
def valid_value(cls, value): def valid_value(cls, value):
if value not in (1, -1, 0): if value not in (1, -1):
raise ValueError("value must be 1, -1, or 0") raise ValueError("value must be 1 or -1")
return value return value
@@ -22,7 +22,7 @@ ENGAGEMENT_ACTIONS: tuple[Action, ...] = (
), ),
body( body(
"value", "value",
"Vote value: 1 to upvote, -1 to downvote, 0 to retract.", "Vote value: 1 to upvote, -1 to downvote (re-send to remove).",
required=True, required=True,
), ),
), ),
@@ -11,7 +11,7 @@ How a request flows through middleware to a router, how the database layer is bu
## Middleware ## Middleware
Seven HTTP middlewares run as a stack around every request, listed outermost first. `response_timing` is the outermost, `refresh_db_snapshot` the innermost, and a `GZipMiddleware` (responses over 512 bytes) wraps the whole stack on top: Six HTTP middlewares run as a stack around every request, listed outermost first. `response_timing` is the outermost and `refresh_db_snapshot` the innermost. Compression is handled by nginx in production; the Python application does not compress responses itself.
| Middleware (outermost first) | Responsibility | | Middleware (outermost first) | Responsibility |
|------------|----------------| |------------|----------------|
+2 -1
View File
@@ -4,7 +4,8 @@ version = "1.0.0"
description = "DevPlace - The Developer Social Network" description = "DevPlace - The Developer Social Network"
requires-python = ">=3.12" requires-python = ">=3.12"
dependencies = [ dependencies = [
"fastapi", "fastapi>=0.110.0",
"starlette>=0.37.0",
"uvicorn[standard]", "uvicorn[standard]",
"jinja2", "jinja2",
"python-multipart", "python-multipart",
-10
View File
@@ -135,13 +135,3 @@ def test_non_ajax_vote_redirects_to_referer(app_server):
) )
assert r.status_code == 302 assert r.status_code == 302
assert r.headers["location"] == "/gists" assert r.headers["location"] == "/gists"
def test_explicit_zero_retracts_vote(app_server):
s_a, a_name = _session_votes()
s_b, _ = _session_votes()
post_uid = _make_post_votes(_uid_votes(a_name))
s_b.post(f"{BASE_URL}/votes/post/{post_uid}", data={"value": "1"}, headers=AJAX_votes)
r = s_b.post(f"{BASE_URL}/votes/post/{post_uid}", data={"value": "0"}, headers=AJAX_votes)
assert r.json()["value"] == 0
assert r.json()["net"] == 0