All source listed below is under MIT license if no LICENSE file stating different is available.
devRanta
Author: retoor retoor@molodetz.nl
An asynchronous Python client for the devRant API. Authentication is only required for write operations; read-only endpoints work without credentials. Packages available in tar and wheel format here.
Running
make run
Testing
Tests cover methods not requiring authentication.
make test
Usage
from devranta.api import Api
api = Api(username="optional", password="optional")
async def list_rants():
async for rant in api.get_rants():
print(rant["user_username"], ":", rant["text"])
See tests for additional examples.
Examples
| Example | Description |
|---|---|
| crawler | Asynchronous data collection with producer-consumer architecture |
| princess | Automated response bot with LLM integration |
devRant API Documentation
Reference for building custom clients.
Base URL
https://devrant.com/api
Authentication
- Uses
dr_tokencookie withtoken_id,token_key, anduser_id. - Required for endpoints needing user authentication.
guid,plat,sid,seidincluded in requests for session tracking.
Endpoints
User Management
- Registering user
- Ommitted, you know why.
- Login User
- URL:
/api/users/auth-token - Method: POST
- Parameters:
app: 3username: User usernamepassword: User passwordguid: Unique identifierplat: 3sid: Session start timeseid: Session event ID
- Response: JSON with
success,auth_token, orerror- Success Example:
{ "success": true, "auth_token": { "id": 18966518, "key": "z6uXRZrQ_Ekx59wfYEjpbnS!fDeVznVqmmKujhT8", "expire_time": 1756765587, "user_id": 18959632 } } - Error Example:
{ "success": false, "error": "Invalid login credentials entered. Please try again." }
- Success Example:
- Description: Authenticates user and returns auth token.
- URL:
- Edit Profile
- URL:
/api/users/me/edit-profile - Method: POST
- Parameters:
app: 3token_id: Token IDtoken_key: Token keyuser_id: User IDguid,plat,sid,seidprofile_about: User bioprofile_skills: User skillsprofile_location: User locationprofile_website: User websiteprofile_github: GitHub username
- Response: JSON with
success- Success Example:
{ "success": true }
- Success Example:
- Description: Updates user profile information.
- URL:
- Forgot Password
- URL:
/api/users/forgot-password - Method: POST
- Parameters:
app: 3username: User usernameguid,plat,sid,seid
- Response: JSON with
success- Success Example:
{ "success": true }
- Success Example:
- Description: Initiates password reset process.
- URL:
- Resend Confirmation Email
- URL:
/api/users/me/resend-confirm - Method: POST
- Parameters:
app: 3token_id,token_key,user_id,guid,plat,sid,seid
- Response: JSON with
success- Success Example:
{ "success": true }
- Success Example:
- Description: Resends account confirmation email.
- URL:
- Delete Account
- URL:
/api/users/me - Method: DELETE
- Parameters:
app: 3token_id,token_key,user_id,guid,plat,sid,seid
- Response: JSON with
success - Description: Deletes user account.
- URL:
- Mark News as Read
- URL:
/api/users/me/mark-news-read - Method: POST
- Parameters:
app: 3token_id,token_key,user_id,guid,plat,sid,seidnews_id: News item ID
- Response: JSON with
success- Success Example:
{ "success": true }
- Success Example:
- Description: Marks a news item as read for logged-in users.
- URL:
Rants
- Get Rant
- URL:
/api/devrant/rants/{rant_id} - Method: GET
- Parameters:
app: 3token_id,token_key,user_id,guid,plat,sid,seidlast_comment_id: 999999999999 (optional)links: 0 (optional)
- Response: JSON with
rant(text, tags),comments,success,subscribed- Success Example:
{ "rant": { "id": 18960811, "text": "You know, I'm getting tired of this HR-speak in job applications, specifically this:\n\n- [tech] has no secrets for you\n\nWhat, really? So I am the undisputed and absolute expert of - let's say - JavaScript? Do you know how long it takes to master that so that it holds no secrets? It even holds secrets to decade-long experts! The same goes for most other technologies in software development.\n\nSigh. Hhhhh. Ree.", "score": 3, "created_time": 1754065322, "attached_image": "", "num_comments": 10, "tags": [ "too-much", "qualifications", "job-hunting" ], "vote_state": 0, "edited": false, "link": "rants/18960811/you-know-im-getting-tired-of-this-hr-speak-in-job-applications-specifically-this", "rt": 1, "rc": 1, "user_id": 1366654, "user_username": "CaptainRant", "user_score": 4179, "user_avatar": { "b": "2a8b9d", "i": "v-37_c-3_b-4_g-m_9-1_1-2_16-6_3-1_8-1_7-1_5-2_12-2_6-3_10-1_2-10_22-2_11-2_18-1_19-3_4-2_20-1_21-2.jpg" }, "user_avatar_lg": { "b": "2a8b9d", "i": "v-37_c-1_b-4_g-m_9-1_1-2_16-6_3-1_8-1_7-1_5-2_12-2_6-3_10-1_2-10_22-2_11-2_18-1_19-3_4-2_20-1_21-2.png" } }, "comments": [], "success": true, "subscribed": 0 }
- Success Example:
- Description: Retrieves a specific rant by ID.
- URL:
- Post Rant
- URL:
/api/devrant/rants - Method: POST
- Parameters (FormData):
app: 3rant: Rant texttags: Comma-separated tagstoken_id,token_key,user_idtype: Rant type IDimage: Optional image file (img/gif)
- Response: JSON with
success,rant_id, orerror- Error Example:
{ "success": false, "error": "It looks like you just posted this same rant! Your connection might have timed out while posting so you might have seen an error, but sometimes the rant still gets posted and in this case it seems it did, so please check :) If this was not the case please contact info@devrant.io. Thanks!" }
- Error Example:
- Description: Creates a new rant.
- URL:
- Edit Rant
- URL:
/api/devrant/rants/{rant_id} - Method: POST
- Parameters (FormData):
app: 3rant: Rant texttags: Comma-separated tagstoken_id,token_key,user_idimage: Optional image file
- Response: JSON with
successorfail_reason- Error Example:
{ "success": false, "fail_reason": "" }
- Error Example:
- Description: Updates an existing rant.
- URL:
- Delete Rant
- URL:
/api/devrant/rants/{rant_id} - Method: DELETE
- Parameters:
app: 3token_id,token_key,user_id,guid,plat,sid,seid
- Response: JSON with
successorerror- Error Example:
{ "success": false, "error": "An unknown error occurred and this rant can't be deleted. Please contact support@devrant.com for help with this." }
- Error Example:
- Description: Deletes a rant.
- URL:
- Vote on Rant
- URL:
/api/devrant/rants/{rant_id}/vote - Method: POST
- Parameters:
app: 3token_id,token_key,user_id,guid,plat,sid,seidvote: 1 (upvote), -1 (downvote), 0 (remove vote)reason: Downvote reason ID (required for downvote)
- Response: JSON with
success,rant, orconfirmed(false if unverified)- Success Example:
{ "success": true, "rant": { "id": 18960811, "text": "You know, I'm getting tired of this HR-speak in job applications, specifically this:\n\n- [tech] has no secrets for you\n\nWhat, really? So I am the undisputed and absolute expert of - let's say - JavaScript? Do you know how long it takes to master that so that it holds no secrets? It even holds secrets to decade-long experts! The same goes for most other technologies in software development.\n\nSigh. Hhhhh. Ree.", "score": 3, "created_time": 1754065322, "attached_image": "", "num_comments": 10, "tags": [ "rant", "too-much", "qualifications", "job-hunting" ], "vote_state": -1, "edited": false, "rt": 1, "rc": 1, "user_id": 1366654, "user_username": "CaptainRant", "user_score": 4180, "user_avatar": { "b": "2a8b9d", "i": "v-37_c-3_b-4_g-m_9-1_1-2_16-6_3-1_8-1_7-1_5-2_12-2_6-3_10-1_2-10_22-2_11-2_18-1_19-3_4-2_20-1_21-2.jpg" }, "user_avatar_lg": { "b": "2a8b9d", "i": "v-37_c-1_b-4_g-m_9-1_1-2_16-6_3-1_8-1_7-1_5-2_12-2_6-3_10-1_2-10_22-2_11-2_18-1_19-3_4-2_20-1_21-2.png" } } }
- Success Example:
- Description: Votes on a rant.
- URL:
- Favorite/Unfavorite Rant
- URL:
/api/devrant/rants/{rant_id}/{favorite|unfavorite} - Method: POST
- Parameters:
app: 3token_id,token_key,user_id,guid,plat,sid,seid
- Response: JSON with
success- Success Example:
{ "success": true }
- Success Example:
- Description: Favorites or unfavorites a rant.
- URL:
- Get Rant Feed
- URL:
/api/devrant/rants - Method: GET
- Parameters:
app: 3token_id,token_key,user_id,guid,plat,sid,seidids: JSON string of IDs (optional)
- Response: JSON with
success,rants,settings,set,wrw,dpp,num_notifs,unread,news- Success Example:
{ "success": true, "rants": [ { "id": 18960811, "text": "You know, I'm getting tired of this HR-speak in job applications, specifically this:\n\n- [tech] has no secrets for you\n\nWhat, really? So I am the undisputed and absolute expert of - let's say - JavaScript? Do you know how long it takes to master that so that it holds no secrets? It even holds secrets to decade-long experts! The same goes for most other technologies in software development.\n\nSigh. Hhhhh. Ree.", "score": 3, "created_time": 1754065322, "attached_image": "", "num_comments": 9, "tags": [ "rant", "too-much", "qualifications", "job-hunting" ], "vote_state": 0, "edited": false, "rt": 1, "rc": 1, "user_id": 1366654, "user_username": "CaptainRant", "user_score": 4179, "user_avatar": { "b": "2a8b9d", "i": "v-37_c-3_b-4_g-m_9-1_1-2_16-6_3-1_8-1_7-1_5-2_12-2_6-3_10-1_2-10_22-2_11-2_18-1_19-3_4-2_20-1_21-2.jpg" }, "user_avatar_lg": { "b": "2a8b9d", "i": "v-37_c-1_b-4_g-m_9-1_1-2_16-6_3-1_8-1_7-1_5-2_12-2_6-3_10-1_2-10_22-2_11-2_18-1_19-3_4-2_20-1_21-2.png" } } // ... more rants ], "settings": { "notif_state": -1, "notif_token": "" }, "set": "688e90b7cf77f", "wrw": 385, "dpp": 0, "num_notifs": 0, "unread": { "total": 0 }, "news": { "id": 356, "type": "intlink", "headline": "Weekly Group Rant", "body": "Tips for staying productive?", "footer": "Add tag 'wk247' to your rant", "height": 100, "action": "grouprant" } }
- Success Example:
- Description: Retrieves rant feed with notification count.
- URL:
Comments
- Get Comment
- URL:
/api/comments/{comment_id} - Method: GET
- Parameters:
app: 3token_id,token_key,user_id,guid,plat,sid,seidlinks: 0 (optional)
- Response: JSON with
comment(body), orerror- Error Example:
{ "success": false, "error": "Invalid comment specified in path." }
- Error Example:
- Description: Retrieves a specific comment by ID.
- URL:
- Post Comment
- URL:
/api/devrant/rants/{rant_id}/comments - Method: POST
- Parameters (FormData):
app: 3comment: Comment texttoken_id,token_key,user_idimage: Optional image file (img/gif)
- Response: JSON with
successorconfirmed(false if unverified)- Success Example:
{ "success": true }
- Success Example:
- Description: Posts a comment on a rant.
- URL:
- Edit Comment
- URL:
/api/comments/{comment_id} - Method: POST
- Parameters (FormData):
app: 3comment: Comment texttoken_id,token_key,user_id
- Response: JSON with
successorfail_reason- Error Example:
{ "success": false, "error": "Invalid comment specified in path." }
- Error Example:
- Description: Updates an existing comment.
- URL:
- Delete Comment
- URL:
/api/comments/{comment_id} - Method: DELETE
- Parameters:
app: 3token_id,token_key,user_id,guid,plat,sid,seid
- Response: JSON with
successorerror- Error Example:
{ "success": false, "error": "Invalid comment specified in path." }
- Error Example:
- Description: Deletes a comment.
- URL:
- Vote on Comment
- URL:
/api/comments/{comment_id}/vote - Method: POST
- Parameters:
app: 3token_id,token_key,user_id,guid,plat,sid,seidvote: 1 (upvote), -1 (downvote), 0 (remove vote)reason: Downvote reason ID (required for downvote)
- Response: JSON with
successorerror- Error Example:
{ "success": false, "error": "Invalid comment specified in path." }
- Error Example:
- Description: Votes on a comment.
- URL:
Notifications
- Get Notification Feed
- URL:
/api/users/me/notif-feed - Method: GET
- Parameters:
app: 3token_id,token_key,user_id,guid,plat,sid,seidext_prof: 1 (optional)last_time: Last notification check time
- Response: JSON with
success,data(items, check_time, username_map, unread, num_unread)- Success Example:
{ "success": true, "data": { "items": [], "check_time": 1754173634, "username_map": [], "unread": { "all": 0, "upvotes": 0, "mentions": 0, "comments": 0, "subs": 0, "total": 0 }, "num_unread": 0 } }
- Success Example:
- Description: Retrieves user notifications.
- URL:
- Clear Notifications
- URL:
/api/users/me/notif-feed - Method: DELETE
- Parameters:
app: 3token_id,token_key,user_id,guid,plat,sid,seid
- Response: JSON with
success- Success Example:
{ "success": true }
- Success Example:
- Description: Clears user notifications.
- URL:
External API
- Beta List Signup
- URL:
https://www.hexicallabs.com/api/beta-list - Method: GET (JSONP)
- Parameters:
email: User emailplatform: Platform nameapp: 3
- Response: JSON with
error- Error Example:
{ "error": "Expecting value: line 1 column 1 (char 0)" }
- Error Example:
- Description: Signs up user for beta list (external service).
- URL:
Notes
- All endpoints expect
app=3for identification. - Authenticated endpoints require
dr_tokencookie withtoken_id,token_key,user_id. guid,plat,sid,seidare used for session tracking.- Image uploads use FormData for rants and comments.
- Downvotes require a reason ID, prompting a modal if not provided.
- Responses typically include
successboolean; errors includeerrororfail_reason. - Cookies (
dr_token,dr_guid,dr_session_start,dr_event_id,dr_feed_sort,dr_theme,dr_rants_viewed,dr_stickers_seen,rant_type_filters,news_seen) manage state and preferences.
| .gitea/workflows | |
| dist | |
| examples | |
| src | |
| .gitignore | |
| api_test_results.json | |
| Makefile | |
| pyproject.toml | |
| README.md | |
| setup.cfg | |
| test.py |