Skip to content

Commit 8da43bf

Browse files
authored
fixed typo (paperscout-python -> paperscout) (#19)
* fixed typo (paperscout-python -> paperscout) * used placeholder and resolved binding issue * addressed coderabbitai review
1 parent 6f35ebb commit 8da43bf

10 files changed

Lines changed: 67 additions & 36 deletions

File tree

.env.example

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@ SLACK_BOT_TOKEN=xoxb-your-bot-token
44

55
# Server
66
PORT=3000
7+
HEALTH_PORT=8080
8+
# Bind address for GET /health (127.0.0.1 = localhost only). Docker Compose sets HEALTH_BIND_HOST=0.0.0.0.
9+
HEALTH_BIND_HOST=127.0.0.1
710

811
# Database (required) — shared PostgreSQL on the host.
912
# When running in Docker, use host.docker.internal to reach the host:

README.md

Lines changed: 25 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
# paperscout-python
1+
# paperscout
22

3-
[![CI](https://github.com/cppalliance/paperscout-python/actions/workflows/ci.yml/badge.svg)](https://github.com/cppalliance/paperscout-python/actions/workflows/ci.yml)
4-
[![CD](https://github.com/cppalliance/paperscout-python/actions/workflows/cd.yml/badge.svg)](https://github.com/cppalliance/paperscout-python/actions/workflows/cd.yml)
3+
[![CI](https://github.com/cppalliance/paperscout/actions/workflows/ci.yml/badge.svg)](https://github.com/cppalliance/paperscout/actions/workflows/ci.yml)
4+
[![CD](https://github.com/cppalliance/paperscout/actions/workflows/cd.yml/badge.svg)](https://github.com/cppalliance/paperscout/actions/workflows/cd.yml)
55

66
WG21 C++ paper tracker with ISO draft probing and Slack notifications.
77

@@ -79,7 +79,7 @@ Go to **App Home** in the left sidebar:
7979
### 6. Configure and Start the Scout
8080

8181
```bash
82-
cd paperscout-python
82+
cd paperscout
8383
cp .env.example .env
8484
```
8585

@@ -172,7 +172,7 @@ The workflow picks the environment from the branch (`refs/heads/main` → `produ
172172

173173
```bash
174174
# On the production server (after Docker, PostgreSQL, and nginx are set up)
175-
git clone https://github.com/cppalliance/paperscout-python.git /opt/paperscout
175+
git clone https://github.com/cppalliance/paperscout.git /opt/paperscout
176176
cd /opt/paperscout
177177
cp .env.example .env # edit with real credentials
178178
docker compose up -d --build
@@ -182,7 +182,7 @@ curl -sf http://localhost:9101/health
182182
On the **staging** server (separate host or separate path on the same host; must match the `staging` environment's `DEPLOY_PATH` and expose `/health` on `HEALTH_PORT`):
183183

184184
```bash
185-
git clone -b develop https://github.com/cppalliance/paperscout-python.git /opt/paperscout-staging
185+
git clone -b develop https://github.com/cppalliance/paperscout.git /opt/paperscout-staging
186186
cd /opt/paperscout-staging
187187
cp .env.example .env # use staging credentials / DB / Slack app as appropriate
188188
docker compose up -d --build
@@ -225,15 +225,23 @@ All parameters are configurable via environment variables or a `.env` file. See
225225
| `SLACK_BOT_TOKEN` | Slack bot token (`xoxb-...`) |
226226
| `DATABASE_URL` | PostgreSQL connection string (`postgresql://user:pass@host:5432/db`) |
227227

228+
### Server
229+
230+
| Variable | Default | Description |
231+
| -------------------- | ----------- | ------------------------------------------------------------------------------------------------------------------------------------------- |
232+
| `PORT` | `3000` | Slack Bolt HTTP listener |
233+
| `HEALTH_PORT` | `8080` | GET `/health` JSON endpoint |
234+
| `HEALTH_BIND_HOST` | `127.0.0.1` | Bind address for the health server (localhost-only). Use `0.0.0.0` inside Docker when publishing ports to the host; see `docker-compose.yml`. |
235+
228236
### Scheduling
229237

230-
| Variable | Default | Description |
231-
| ----------------------- | ------- | ------------------------------------------------------ |
232-
| `POLL_INTERVAL_MINUTES` | `30` | Main polling cycle interval |
233-
| `POLL_OVERRUN_COOLDOWN_SECONDS` | `300` | Minimum sleep after a poll cycle that overran the interval (avoids tight loops when work or errors stretch a cycle) |
234-
| `ENABLE_BULK_WG21` | `true` | Fetch wg21.link/index.json each cycle |
235-
| `ENABLE_BULK_OPENSTD` | `true` | Reserved for open-std.org scraping (not yet scheduled) |
236-
| `ENABLE_ISO_PROBE` | `true` | Run isocpp.org HEAD probing each cycle |
238+
| Variable | Default | Description |
239+
| ------------------------------- | ------- | ------------------------------------------------------------------------------------------------------------------- |
240+
| `POLL_INTERVAL_MINUTES` | `30` | Main polling cycle interval |
241+
| `POLL_OVERRUN_COOLDOWN_SECONDS` | `300` | Minimum sleep after a poll cycle that overran the interval (avoids tight loops when work or errors stretch a cycle) |
242+
| `ENABLE_BULK_WG21` | `true` | Fetch wg21.link/index.json each cycle |
243+
| `ENABLE_BULK_OPENSTD` | `true` | Reserved for open-std.org scraping (not yet scheduled) |
244+
| `ENABLE_ISO_PROBE` | `true` | Run isocpp.org HEAD probing each cycle |
237245

238246
### Probe Prefixes / Extensions
239247

@@ -302,7 +310,7 @@ All parameters are configurable via environment variables or a `.env` file. See
302310
## Architecture
303311

304312
```
305-
paperscout-python/
313+
paperscout/
306314
src/paperscout/
307315
__main__.py Entry point; wires together all components
308316
config.py All settings via pydantic-settings
@@ -312,7 +320,7 @@ paperscout-python/
312320
scout.py Slack Bolt app, MessageQueue, notify_channel, notify_users
313321
storage.py PaperCache, ProbeState, UserWatchlist (all PostgreSQL-backed)
314322
db.py ThreadedConnectionPool init and schema DDL
315-
health.py HTTP health-check endpoint (GET /health on port 8080)
323+
health.py HTTP health-check endpoint (GET /health; bind via HEALTH_BIND_HOST)
316324
data/ Log files (gitignored); all other state lives in PostgreSQL
317325
deploy/
318326
paperscout.conf Reference nginx site config (443 → 3000, /health → 8080)
@@ -380,8 +388,8 @@ The `Last-Modified` timestamp is shown in every notification message.
380388
### Setup
381389

382390
```bash
383-
git clone https://github.com/cppalliance/paperscout-python.git
384-
cd paperscout-python
391+
git clone https://github.com/cppalliance/paperscout.git
392+
cd paperscout
385393
python -m venv .venv
386394
source .venv/bin/activate # Windows: .venv\Scripts\activate
387395
pip install -e ".[dev]"

deploy/SERVER_SETUP.md

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@
33
Step-by-step guide for provisioning a fresh Ubuntu 22.04 server to run
44
paperscout alongside other apps that share the same PostgreSQL and nginx.
55

6+
Substitute **`<deploy-user>`** with your SSH/deploy UNIX username wherever it
7+
appears (file ownership, Docker group).
8+
69
---
710

811
## 1. System basics
@@ -41,7 +44,7 @@ sudo apt update
4144
sudo apt install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin
4245

4346
# Let the deploy user run docker without sudo
44-
sudo usermod -aG docker gcp-cppdigest
47+
sudo usermod -aG docker <deploy-user>
4548
newgrp docker
4649
```
4750

@@ -136,15 +139,15 @@ sudo apt install -y nginx
136139

137140
# Obtain a Let's Encrypt certificate (skip if already done for this domain)
138141
sudo apt install -y certbot python3-certbot-nginx
139-
sudo certbot --nginx -d dev.cppdigest.org
142+
sudo certbot --nginx -d your-domain.example.org
140143
```
141144

142-
Certbot creates a server block for `dev.cppdigest.org` in the default
145+
Certbot creates a server block for `your-domain.example.org` in the default
143146
nginx config. Add the paperscout location blocks **inside that existing
144147
server block** (do NOT create a separate server block -- nginx will
145148
ignore it in favour of the first match).
146149

147-
Open the config and find the `dev.cppdigest.org` server block with
150+
Open the config and find the `your-domain.example.org` server block with
148151
`listen 443 ssl;`. Add these lines before its closing `}`:
149152

150153
```nginx
@@ -177,8 +180,8 @@ Clone the repo into `/opt/paperscout`:
177180

178181
```bash
179182
sudo mkdir -p /opt
180-
sudo git clone https://github.com/cppalliance/paperscout-python.git /opt/paperscout
181-
sudo chown -R gcp-cppdigest:gcp-cppdigest /opt/paperscout
183+
sudo git clone https://github.com/<org>/<repo>.git /opt/paperscout
184+
sudo chown -R <deploy-user>:<deploy-user> /opt/paperscout
182185
```
183186

184187
Create the `.env` file:
@@ -197,6 +200,10 @@ The `DATABASE_URL` should use `host.docker.internal`:
197200
DATABASE_URL=postgresql://paperscout:<password>@host.docker.internal:5432/paperscout
198201
```
199202

203+
The Docker Compose file sets **`HEALTH_BIND_HOST=0.0.0.0`** so the health
204+
HTTP server accepts connections from Docker’s port publishing (the default
205+
`127.0.0.1` bind is for bare-metal / localhost-only use).
206+
200207
> **Note:** If the password contains special characters, they must be
201208
> percent-encoded in the URL (e.g. `@``%40`, `!``%21`).
202209
> Use `python3 -c "import urllib.parse; print(urllib.parse.quote('<password>', safe=''))"` to encode it.
@@ -248,7 +255,7 @@ Configure these in the repo under **Settings → Secrets and variables → Actio
248255
| Secret | Purpose |
249256
| ---------------- | ----------------------------------- |
250257
| `SERVER_HOST` | Server IP or hostname |
251-
| `SERVER_USER` | SSH username (e.g. `gcp-cppdigest`) |
258+
| `SERVER_USER` | SSH username (e.g. `<deploy-user>`) |
252259
| `SERVER_SSH_KEY` | Private SSH key for the deploy user |
253260
| `SERVER_PORT` | SSH port (optional, defaults to 22) |
254261

deploy/paperscout.conf

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
server {
22
listen 443 ssl;
3-
server_name dev.cppdigest.org;
3+
server_name your-domain.example.org;
44

5-
ssl_certificate /etc/letsencrypt/live/dev.cppdigest.org/fullchain.pem;
6-
ssl_certificate_key /etc/letsencrypt/live/dev.cppdigest.org/privkey.pem;
5+
ssl_certificate /etc/letsencrypt/live/your-domain.example.org/fullchain.pem;
6+
ssl_certificate_key /etc/letsencrypt/live/your-domain.example.org/privkey.pem;
77

88
# Health endpoint — must come before the general /paperscout/ block
99
# because nginx uses longest-prefix matching.

docker-compose.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ services:
55
- "127.0.0.1:9100:3000"
66
- "127.0.0.1:9101:8080"
77
env_file: .env
8+
environment:
9+
HEALTH_BIND_HOST: "0.0.0.0"
810
extra_hosts:
911
- "host.docker.internal:host-gateway"
1012
logging:

docs/onboarding.md

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,8 @@ Supporting directories: [`tests/`](../tests/) (pytest), [`deploy/`](../deploy/)
3131
### 1. Clone and virtual environment
3232

3333
```bash
34-
git clone https://github.com/cppalliance/paperscout-python.git
35-
cd paperscout-python
34+
git clone https://github.com/cppalliance/paperscout.git
35+
cd paperscout
3636
python -m venv .venv
3737
source .venv/bin/activate # Windows Git Bash: source .venv/Scripts/activate
3838
pip install -e ".[dev]"
@@ -197,13 +197,15 @@ Every key from [`.env.example`](../.env.example) is listed below. Names in `.env
197197
### Storage and logging
198198

199199
| Variable | Default | Meaning |
200-
| -------------------- | -------- | ------------------------------------------------------------- |
200+
| -------------------- | -------- | ------------------------------------------------------------- | --------------------------------------------------------------------------- |
201201
| `DATA_DIR` | `./data` | Log directory (and local file layout); created if missing. |
202202
| `CACHE_TTL_HOURS` | `1` | Staleness window for cached wg21 index blob in Postgres. |
203203
| `LOG_LEVEL` | `INFO` | Console/file log level (`DEBUG`, `INFO`, `WARNING`, `ERROR`). |
204204
| `LOG_RETENTION_DAYS` | `7` | Days of rotated log files to retain. |
205+
| `HEALTH_PORT` | No | `8080` | Port for the `GET /health` endpoint. |
206+
| `HEALTH_BIND_HOST` | No | `127.0.0.1` | Bind host for health server; use `0.0.0.0` in Docker when publishing ports. |
205207

206-
**Note:** `health_port` (default `8080`) exists in [Settings](../src/paperscout/config.py) but is not listed in `.env.example`. You can still set `HEALTH_PORT` in `.env` if you need to override the default.
208+
Docker Compose sets `HEALTH_BIND_HOST=0.0.0.0` so the health endpoint accepts connections through published ports.
207209

208210
## Scheduling (asyncio loop)
209211

src/paperscout/__main__.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,13 @@ def _on_poll_result(result):
116116

117117
register_handlers(app, user_watchlist, state, paper_count_fn, launch_time)
118118

119-
start_health_server(settings.health_port, launch_time, state, paper_count_fn)
119+
start_health_server(
120+
settings.health_port,
121+
launch_time,
122+
state,
123+
paper_count_fn,
124+
bind_host=settings.health_bind_host,
125+
)
120126
log.info("Starting Slack Bolt app on port %d", settings.port)
121127
bolt_thread = threading.Thread(
122128
target=app.start,

src/paperscout/config.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ class Settings(BaseSettings):
2222
slack_bot_token: str = ""
2323
port: int = 3000
2424
health_port: int = 8080
25+
# Empty string means all interfaces (0.0.0.0); Docker Compose sets HEALTH_BIND_HOST=0.0.0.0.
26+
health_bind_host: str = "127.0.0.1"
2527

2628
# -- Scheduling --
2729
poll_interval_minutes: int = 30

src/paperscout/health.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -66,8 +66,9 @@ def start_health_server(
6666
launch_time: datetime,
6767
state,
6868
paper_count_fn: Callable[[], int],
69+
bind_host: str = "127.0.0.1",
6970
) -> HTTPServer:
70-
"""Start the ``/health`` HTTP server on *port* in a daemon thread."""
71+
"""Start the ``/health`` HTTP server on *bind_host*:*port* in a daemon thread."""
7172

7273
handler = type(
7374
"_BoundHealthHandler",
@@ -79,8 +80,8 @@ def start_health_server(
7980
},
8081
)
8182

82-
server = HTTPServer(("", port), handler)
83+
server = HTTPServer((bind_host, port), handler)
8384
thread = threading.Thread(target=server.serve_forever, daemon=True, name="health")
8485
thread.start()
85-
log.info("Health endpoint listening on port %d", port)
86+
log.info("Health endpoint listening on %s:%d", bind_host, port)
8687
return server

tests/test_health.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ def _find_free_port() -> int:
1515
import socket
1616

1717
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
18-
s.bind(("", 0))
18+
s.bind(("127.0.0.1", 0))
1919
return s.getsockname()[1]
2020

2121

0 commit comments

Comments
 (0)