Skip to content

Commit a688a13

Browse files
authored
Add PRAW to Devvit web AI migration guide (#156)
## 💸 TL;DR Adds an LLM guide for migrating a PRAW bot to Devvit. ## 📜 Details [Design Doc](<!-- insert Google Doc link here if applicable -->) [Jira](<!-- insert Jira link if applicable -->) <!-- Add additional details required for the PR: breaking changes, screenshots, external dependency changes --> ## 🧪 Testing Steps / Validation <!-- add details on how this PR has been tested, include reproductions and screenshots where applicable --> ## ✅ Checks <!-- Make sure your pr passes the CI checks and do check the following fields as needed - --> - [x] CI tests (if present) are passing - [x] Adheres to code style for repo - [ ] Contributor License Agreement (CLA) completed if not a Reddit employee
1 parent c8bb880 commit a688a13

6 files changed

Lines changed: 548 additions & 100 deletions

File tree

Lines changed: 206 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,206 @@
1+
# Migrating with AI
2+
3+
Use an AI assistant to help port a PRAW app to Devvit Web, but keep the migration review-driven. The assistant should inspect the PRAW app first, explain its migration plan, call out gaps, and migrate one behavior at a time. You should review the generated code and test the migrated app thoroughly.
4+
5+
This guide focuses on the AI-assisted workflow. For the API-by-API mapping, use [Migration Basics](./basics.md#migration-basics).
6+
7+
## Ground rules
8+
9+
Give the assistant these constraints before it edits code:
10+
11+
- Treat `app-to-migrate/` as read-only reference material.
12+
- Make required changes in the Devvit app, not in the copied PRAW source.
13+
- Use `@devvit/web`; do not migrate to `@devvit/public-api`.
14+
- Explain why each major PRAW pattern maps to a Devvit capability.
15+
- Verify nontrivial Reddit API mappings against PRAW behavior and Devvit docs before coding.
16+
- Do not ask for secrets in chat and do not commit secrets, OAuth tokens, `.env` values, or developer credentials.
17+
- Keep a gap list for behavior that cannot be migrated directly.
18+
19+
## 1. Prepare the target app
20+
21+
Start with a clean Devvit Web app from the [app quickstart](../../../quickstart/quickstart.md) or [mod tool quickstart](../../../quickstart/quickstart-mod-tool.md). If the PRAW app is primarily a moderator tool, use the patterns in [Build a Mod Tool - Three Strikes](../../../examples/tutorials/mod-tool.md).
22+
23+
If you want to keep the old app name, use a placeholder Devvit app name during migration and test the app first. Handle name migration later with the Devvit team through [Discord](https://developers.reddit.com/discord).
24+
25+
Copy the PRAW app into `app-to-migrate/` at the Devvit project root, add that folder to `.gitignore`, and commit the Devvit project before AI edits anything. Copy the source app; do not move the only working copy.
26+
27+
If your coding assistant supports docs or repo skills, enable Devvit docs and PRAW docs before migration. The assistant will need both sides of the API behavior to make accurate replacements.
28+
29+
## 2. Make the AI inspect first
30+
31+
Do not start with "convert this app." Start with an inventory pass that produces a plan but does not edit files.
32+
33+
```text
34+
Migrate the PRAW app in app-to-migrate/ to Devvit Web.
35+
36+
Rules:
37+
- Treat app-to-migrate/ as read-only reference material.
38+
- Use @devvit/web only; do not use @devvit/public-api.
39+
- Do not edit files yet.
40+
- Inspect devvit.json, package.json, src/, and app-to-migrate/.
41+
42+
Report:
43+
- PRAW entrypoints and startup commands
44+
- Reddit API calls and object methods
45+
- subreddit.stream, mod.stream, polling, cron, and while True loops
46+
- local storage, SQL, files, pickle, JSON state, and cache usage
47+
- environment variables, secrets, OAuth credentials, and app config
48+
- external HTTP domains and webhook integrations
49+
- CLI, admin, moderator, and maintenance flows
50+
- dependencies that are Python-only, native, or not portable to Devvit
51+
- tests, manual test cases, and untested behavior
52+
- direct Devvit mappings, risky mappings, and unsupported gaps
53+
54+
For each nontrivial PRAW API replacement, cite the PRAW behavior and the
55+
Devvit API or capability you plan to use.
56+
```
57+
58+
Review the report before allowing edits. A useful report should name the files and functions that own each behavior, the Devvit surface that will replace it, and any behavior that needs a product decision instead of a direct port.
59+
60+
## 3. Turn the report into a migration plan
61+
62+
Ask the assistant to produce a small migration plan from the inventory. The plan should use existing Devvit docs instead of restating setup steps.
63+
64+
| PRAW pattern | Devvit decision |
65+
|--------------|-----------------|
66+
| `praw.Reddit(...)`, OAuth setup, bot tokens | Remove token handling and configure Reddit permissions in `devvit.json`. |
67+
| `subreddit.stream.*`, `mod.stream.*`, incoming webhooks | Use [triggers](../../../capabilities/server/triggers.mdx) or declared [external endpoints](../../../capabilities/server/external-endpoints.mdx). |
68+
| `while True`, `time.sleep`, cron, pollers | Use [scheduler](../../../capabilities/server/scheduler.mdx) jobs with bounded batches. |
69+
| SQLite, JSON files, pickle, local disk | Use [Redis](../../../capabilities/server/redis.mdx), [Blob Storage](../../../capabilities/server/blob-storage.mdx), or an external service. |
70+
| `.env`, `os.getenv`, process config | Use [Settings & Secrets](../../../capabilities/server/settings-and-secrets.mdx). |
71+
| `requests` or `aiohttp` | Use server-side [HTTP Fetch](../../../capabilities/server/http-fetch.mdx) with explicit domains. |
72+
| CLI admin commands | Use moderator [menu actions](../../../capabilities/client/menu-actions.mdx), [forms](../../../capabilities/client/forms.mdx), or settings. |
73+
| Repeated reads of public Reddit or third-party data | Use [Cache Helper](../../../capabilities/server/cache-helper.md) when shared short-term caching is appropriate. |
74+
| Local logs, shell access, Sentry, Datadog | Use `console.log`, `console.info`, `console.error`, and [Logs and Debugging](../../tools/logs.md). |
75+
| Local bot process tests | Use [@devvit/test](../../tools/devvit_test.mdx) plus mocks for unsupported APIs and third-party fetch calls. |
76+
77+
Do not approve a broad rewrite until the plan covers `devvit.json`, storage, secrets, external domains, tests, and every PRAW entrypoint.
78+
79+
## 4. Configure capabilities before business logic
80+
81+
Have the assistant configure the Devvit app shape before it ports behavior. This makes the migration easier to review because each endpoint, trigger, scheduled job, setting, and permission has an explicit home.
82+
83+
```text
84+
Update only the Devvit app configuration and endpoint skeletons.
85+
86+
Configure the minimum required:
87+
- permissions.reddit
88+
- permissions.http.domains
89+
- triggers
90+
- scheduler jobs
91+
- menu actions and forms
92+
- settings and secrets definitions
93+
- storage-related imports or wrappers
94+
- server endpoints
95+
96+
Do not port business logic yet.
97+
Do not add secret values.
98+
Explain why each capability is needed.
99+
```
100+
101+
Set secret values yourself by following [Settings & Secrets](../../../capabilities/server/settings-and-secrets.mdx). If settings or secrets need to be registered before testing, use the normal [Devvit CLI](../../tools/devvit_cli.mdx) upload flow.
102+
103+
Request HTTP domain approval early when the PRAW app calls third-party services. Keep the allow-list to exact hostnames the app needs.
104+
105+
## 5. Migrate one behavior slice at a time
106+
107+
A behavior slice is one complete workflow, such as "remove comments containing a banned phrase," "post a weekly thread," "sync modmail labels," or "show a moderator form and save the result." Migrating by slice keeps the AI from mixing unrelated changes and makes review practical.
108+
109+
Use a prompt like this for each slice:
110+
111+
```text
112+
Migrate only this behavior: <describe one PRAW workflow>.
113+
114+
Use the inventory and migration plan.
115+
Keep app-to-migrate/ read-only.
116+
Use @devvit/web only.
117+
Prefer the smallest Devvit implementation that preserves behavior.
118+
Update tests for this behavior.
119+
After editing, summarize:
120+
- files changed
121+
- PRAW behavior replaced
122+
- Devvit APIs and capabilities used
123+
- behavior intentionally changed
124+
- tests added or updated
125+
- remaining gaps
126+
```
127+
128+
After each slice, review the diff, run the relevant tests, and update the gap list. If the assistant finds a new gap, make a decision before it writes a workaround.
129+
130+
## 6. Watch for Devvit-specific design changes
131+
132+
Some PRAW patterns should not be ported literally:
133+
134+
| Pattern to flag | What to do instead |
135+
|-----------------|--------------------|
136+
| One bot process serving many subreddits with shared local state | Design for subreddit-scoped installations. Use an external service through HTTP Fetch when you need cross-community state. |
137+
| Infinite streams, daemons, open sockets, or background workers | Use triggers for Reddit events and scheduler jobs for periodic work. Save progress in Redis for batch jobs. |
138+
| Large migrations, cleanup jobs, or historical backfills | Process bounded batches, store a cursor or progress marker, and schedule follow-up work. |
139+
| SQL schemas copied directly into Redis | Redesign around the state the Devvit app actually needs. Use Redis for hot state, Blob Storage for larger records, or an external service for relational data. |
140+
| Iterating over every Redis key later | Track key names in known collection keys. Do not rely on discovering all keys later with a global scan. |
141+
| Large Redis payloads or permanent histories | Use TTLs, bounded histories, Blob Storage, or `redisCompressed` where appropriate. |
142+
| OAuth refresh, praw.ini, client secrets, bot passwords | Remove them. Devvit provides platform-managed Reddit access through app installation and permissions. |
143+
| `process.env` or `os.getenv` for runtime config | Define settings and secrets, then read them from the Devvit server. |
144+
| Python-only libraries, native packages, or local binaries | Replace them with TypeScript packages that work in Devvit, or move that work to an external service. |
145+
| Admin work performed through a terminal | Build moderator-only menu actions, forms, settings, or maintenance endpoints. |
146+
| Private user data such as saved posts, upvoted posts, friends, or user subreddit lists | Redesign around public Reddit data or explicit user actions. |
147+
| Existing production data import or app-name migration | Plan it with the Devvit team through [Discord](https://developers.reddit.com/discord). |
148+
149+
Make the assistant explain these choices in the migration summary. The goal is not just converted code; it is a Devvit app that fits the platform.
150+
151+
## 7. Test the migrated behavior
152+
153+
Ask the assistant to add tests while it migrates each slice, not after the entire app has been rewritten.
154+
155+
Prioritize tests for:
156+
157+
- trigger handlers and event payload parsing
158+
- scheduler jobs, batching, cursors, and retry behavior
159+
- menu actions, forms, and validation
160+
- Redis reads and writes
161+
- settings and secrets reads
162+
- Reddit API calls and `runAs` choices
163+
- third-party fetch success and failure paths
164+
- idempotency for events that may be retried
165+
- unsupported behavior that should fail clearly
166+
167+
Use [@devvit/test](../../tools/devvit_test.mdx) for backend behavior. Mock third-party fetch calls and any Reddit API methods that are not available in the test harness.
168+
169+
## 8. Re-review against the PRAW app
170+
171+
When the assistant says the migration is complete, make it perform a second inventory pass against `app-to-migrate/`.
172+
173+
```text
174+
Re-review app-to-migrate/ against the migrated Devvit app.
175+
176+
Do not edit files yet.
177+
List every PRAW entrypoint, command, stream handler, scheduled job, data write,
178+
moderation action, external API call, setting, and secret.
179+
180+
For each item, mark one:
181+
- migrated
182+
- intentionally changed
183+
- unsupported with accepted gap
184+
- missed and still needs work
185+
```
186+
187+
If anything is missed, migrate another slice and repeat the review. Do not call the migration complete because the app builds; call it complete when every original workflow is migrated or explicitly accepted as a gap.
188+
189+
## 9. Playtest and launch
190+
191+
Use [Playtest](../../tools/playtest.md) in a test subreddit and exercise the migrated workflows with real posts, comments, moderator actions, settings, and scheduled jobs. Use [Logs and Debugging](../../tools/logs.md) to inspect failures.
192+
193+
Before launch, check:
194+
195+
- `app-to-migrate/` was not modified.
196+
- The migrated code imports from `@devvit/web` packages, not `@devvit/public-api`.
197+
- No secrets, OAuth tokens, `.env` values, or developer credentials are in code, docs, tests, or chat transcripts.
198+
- `devvit.json` declares every required Reddit, HTTP, trigger, scheduler, menu, form, setting, secret, endpoint, and storage capability.
199+
- Redis keys that need later iteration are tracked through known collection keys.
200+
- Long-running work is batched and resumable.
201+
- External domains and external endpoints are documented.
202+
- Tests cover the migrated business logic and failure paths.
203+
- Manual playtest coverage includes Reddit UI flows that tests cannot cover.
204+
- Remaining gaps have an explicit owner and path forward.
205+
206+
When the app is ready for review, follow the [launch guide](../../launch/launch-guide.md).

0 commit comments

Comments
 (0)