diff --git a/surfsense_backend/tests/unit/scrapers/reddit/fixtures/sample_listing.json b/surfsense_backend/tests/unit/scrapers/reddit/fixtures/sample_listing.json
new file mode 100644
index 000000000..d984552a9
--- /dev/null
+++ b/surfsense_backend/tests/unit/scrapers/reddit/fixtures/sample_listing.json
@@ -0,0 +1 @@
+{"kind": "Listing", "data": {"after": "t3_1ugsdwl", "dist": 25, "modhash": "", "geo_filter": null, "children": [{"kind": "t3", "data": {"approved_at_utc": null, "subreddit": "Python", "selftext": "Post all of your code/projects/showcases/AI slop here. \n\nRecycles once a month.", "author_fullname": "t2_6l4z3", "saved": false, "mod_reason_title": null, "gilded": 0, "clicked": false, "title": "Showcase Thread", "link_flair_richtext": [{"e": "text", "t": "Showcase"}], "subreddit_name_prefixed": "r/Python", "hidden": false, "pwls": 6, "link_flair_css_class": "showcase", "downs": 0, "thumbnail_height": null, "top_awarded_type": null, "hide_score": false, "name": "t3_1tws1w7", "quarantine": false, "link_flair_text_color": "light", "upvote_ratio": 0.89, "author_flair_background_color": null, "subreddit_type": "public", "ups": 29, "total_awards_received": 0, "media_embed": {}, "thumbnail_width": null, "author_flair_template_id": null, "is_original_content": false, "user_reports": [], "secure_media": null, "is_reddit_media_domain": false, "is_meta": false, "category": null, "secure_media_embed": {}, "link_flair_text": "Showcase", "can_mod_post": false, "score": 29, "approved_by": null, "is_created_from_ads_ui": false, "author_premium": true, "thumbnail": "self", "edited": false, "author_flair_css_class": null, "author_flair_richtext": [], "gildings": {}, "content_categories": null, "is_self": true, "mod_note": null, "created": 1780589106.0, "link_flair_type": "richtext", "wls": 6, "removed_by_category": null, "banned_by": null, "author_flair_type": "text", "domain": "self.Python", "allow_live_comments": false, "selftext_html": "
Post all of your code/projects/showcases/AI slop here.
\n\n
Recycles once a month.
\n
", "likes": null, "suggested_sort": null, "banned_at_utc": null, "view_count": null, "archived": false, "no_follow": false, "is_crosspostable": false, "pinned": false, "over_18": false, "all_awardings": [], "awarders": [], "media_only": false, "link_flair_template_id": "f35fb004-c1ff-11ee-8305-565bc5d0cc73", "can_gild": false, "spoiler": false, "locked": false, "author_flair_text": null, "treatment_tags": [], "visited": false, "removed_by": null, "num_reports": null, "distinguished": null, "subreddit_id": "t5_2qh0y", "author_is_blocked": false, "mod_reason_by": null, "removal_reason": null, "link_flair_background_color": "#ff66ac", "id": "1tws1w7", "is_robot_indexable": true, "report_reasons": null, "author": "AutoModerator", "discussion_type": null, "num_comments": 207, "send_replies": true, "contest_mode": false, "mod_reports": [], "author_patreon_flair": false, "author_flair_text_color": null, "permalink": "/r/Python/comments/1tws1w7/showcase_thread/", "stickied": true, "url": "https://www.reddit.com/r/Python/comments/1tws1w7/showcase_thread/", "subreddit_subscribers": 1493425, "created_utc": 1780589106.0, "num_crossposts": 0, "media": null, "is_video": false}}, {"kind": "t3", "data": {"approved_at_utc": null, "subreddit": "Python", "selftext": "# Weekly Thread: Resource Request and Sharing \ud83d\udcda\n\nStumbled upon a useful Python resource? Or are you looking for a guide on a specific topic? Welcome to the Resource Request and Sharing thread!\n\n## How it Works:\n\n1. **Request**: Can't find a resource on a particular topic? Ask here!\n2. **Share**: Found something useful? Share it with the community.\n3. **Review**: Give or get opinions on Python resources you've used.\n\n## Guidelines:\n\n* Please include the type of resource (e.g., book, video, article) and the topic.\n* Always be respectful when reviewing someone else's shared resource.\n\n## Example Shares:\n\n1. **Book**: [\"Fluent Python\"](https://www.amazon.com/Fluent-Python-Concise-Effective-Programming/dp/1491946008) \\- Great for understanding Pythonic idioms.\n2. **Video**: [Python Data Structures](https://www.youtube.com/watch?v=pkYVOmU3MgA) \\- Excellent overview of Python's built-in data structures.\n3. **Article**: [Understanding Python Decorators](https://realpython.com/primer-on-python-decorators/) \\- A deep dive into decorators.\n\n## Example Requests:\n\n1. **Looking for**: Video tutorials on web scraping with Python.\n2. **Need**: Book recommendations for Python machine learning.\n\nShare the knowledge, enrich the community. Happy learning! \ud83c\udf1f", "author_fullname": "t2_6l4z3", "saved": false, "mod_reason_title": null, "gilded": 0, "clicked": false, "title": "Saturday Daily Thread: Resource Request and Sharing! Daily Thread", "link_flair_richtext": [{"a": ":pythonLogo:", "e": "emoji", "u": "https://emoji.redditmedia.com/8yxdpg6xxnr71_t5_2qh0y/pythonLogo"}, {"e": "text", "t": " Daily Thread"}], "subreddit_name_prefixed": "r/Python", "hidden": false, "pwls": 6, "link_flair_css_class": "daily-thread", "downs": 0, "thumbnail_height": null, "top_awarded_type": null, "hide_score": false, "name": "t3_1umu29k", "quarantine": false, "link_flair_text_color": "light", "upvote_ratio": 1.0, "author_flair_background_color": null, "subreddit_type": "public", "ups": 7, "total_awards_received": 0, "media_embed": {}, "thumbnail_width": null, "author_flair_template_id": null, "is_original_content": false, "user_reports": [], "secure_media": null, "is_reddit_media_domain": false, "is_meta": false, "category": null, "secure_media_embed": {}, "link_flair_text": ":pythonLogo: Daily Thread", "can_mod_post": false, "score": 7, "approved_by": null, "is_created_from_ads_ui": false, "author_premium": true, "thumbnail": "self", "edited": false, "author_flair_css_class": null, "author_flair_richtext": [], "gildings": {}, "post_hint": "self", "content_categories": null, "is_self": true, "mod_note": null, "created": 1783123215.0, "link_flair_type": "richtext", "wls": 6, "removed_by_category": null, "banned_by": null, "author_flair_type": "text", "domain": "self.Python", "allow_live_comments": false, "selftext_html": "Weekly Thread: Resource Request and Sharing \ud83d\udcda
\n\n
Stumbled upon a useful Python resource? Or are you looking for a guide on a specific topic? Welcome to the Resource Request and Sharing thread!
\n\n
How it Works:
\n\n
\n- Request: Can't find a resource on a particular topic? Ask here!
\n- Share: Found something useful? Share it with the community.
\n- Review: Give or get opinions on Python resources you've used.
\n
\n\n
Guidelines:
\n\n
\n- Please include the type of resource (e.g., book, video, article) and the topic.
\n- Always be respectful when reviewing someone else's shared resource.
\n
\n\n
Example Shares:
\n\n
\n- Book: "Fluent Python" - Great for understanding Pythonic idioms.
\n- Video: Python Data Structures - Excellent overview of Python's built-in data structures.
\n- Article: Understanding Python Decorators - A deep dive into decorators.
\n
\n\n
Example Requests:
\n\n
\n- Looking for: Video tutorials on web scraping with Python.
\n- Need: Book recommendations for Python machine learning.
\n
\n\n
Share the knowledge, enrich the community. Happy learning! \ud83c\udf1f
\n
", "likes": null, "suggested_sort": null, "banned_at_utc": null, "view_count": null, "archived": false, "no_follow": false, "is_crosspostable": false, "pinned": false, "over_18": false, "preview": {"images": [{"source": {"url": "https://external-preview.redd.it/wyRlnnC4nIHWRfWMUIBnHvHMsP98N9mROJtKXbnwKWI.png?auto=webp&s=8cdb17f0919f23f3fc3c0bd9dac21cd40118adda", "width": 1910, "height": 1000}, "resolutions": [{"url": "https://external-preview.redd.it/wyRlnnC4nIHWRfWMUIBnHvHMsP98N9mROJtKXbnwKWI.png?width=108&crop=smart&auto=webp&s=c7ef9713fb4fbf51d0d7da30fb558f95324a395b", "width": 108, "height": 56}, {"url": "https://external-preview.redd.it/wyRlnnC4nIHWRfWMUIBnHvHMsP98N9mROJtKXbnwKWI.png?width=216&crop=smart&auto=webp&s=70f4ef0366eafa569960666b4537977954dc4da4", "width": 216, "height": 113}, {"url": "https://external-preview.redd.it/wyRlnnC4nIHWRfWMUIBnHvHMsP98N9mROJtKXbnwKWI.png?width=320&crop=smart&auto=webp&s=e88e6f574ea2b6abf3644be5140a1ed8ad6d613c", "width": 320, "height": 167}, {"url": "https://external-preview.redd.it/wyRlnnC4nIHWRfWMUIBnHvHMsP98N9mROJtKXbnwKWI.png?width=640&crop=smart&auto=webp&s=290ace7209dd3df0a237ec970a6a8b1662d523e1", "width": 640, "height": 335}, {"url": "https://external-preview.redd.it/wyRlnnC4nIHWRfWMUIBnHvHMsP98N9mROJtKXbnwKWI.png?width=960&crop=smart&auto=webp&s=421952297faebb04d1038184216c053ab1f0bb56", "width": 960, "height": 502}, {"url": "https://external-preview.redd.it/wyRlnnC4nIHWRfWMUIBnHvHMsP98N9mROJtKXbnwKWI.png?width=1080&crop=smart&auto=webp&s=2e3704dd3e397c6dbebe004c6cce33e8cd82d316", "width": 1080, "height": 565}], "variants": {}, "id": "wyRlnnC4nIHWRfWMUIBnHvHMsP98N9mROJtKXbnwKWI"}], "enabled": false}, "all_awardings": [], "awarders": [], "media_only": false, "link_flair_template_id": "6c024934-de3f-11ea-a05a-0ea86b2be9a1", "can_gild": false, "spoiler": false, "locked": false, "author_flair_text": null, "treatment_tags": [], "visited": false, "removed_by": null, "num_reports": null, "distinguished": null, "subreddit_id": "t5_2qh0y", "author_is_blocked": false, "mod_reason_by": null, "removal_reason": null, "link_flair_background_color": "#00a6a5", "id": "1umu29k", "is_robot_indexable": true, "report_reasons": null, "author": "AutoModerator", "discussion_type": null, "num_comments": 2, "send_replies": false, "contest_mode": false, "mod_reports": [], "author_patreon_flair": false, "author_flair_text_color": null, "permalink": "/r/Python/comments/1umu29k/saturday_daily_thread_resource_request_and/", "stickied": true, "url": "https://www.reddit.com/r/Python/comments/1umu29k/saturday_daily_thread_resource_request_and/", "subreddit_subscribers": 1493425, "created_utc": 1783123215.0, "num_crossposts": 0, "media": null, "is_video": false}}, {"kind": "t3", "data": {"approved_at_utc": null, "subreddit": "Python", "selftext": "I have this really messy code scattered in 5 files, it s not that long abt 4000 lines. \nadding a new feature started feeling like a pain, \nI hate to deliver this tomorrow, and it s not meant to be scalable. \nshould i refactor or add the features ? \n\nor just add the features and keep the code structure unchanged", "author_fullname": "t2_2h7k9mb406", "saved": false, "mod_reason_title": null, "gilded": 0, "clicked": false, "title": "refactor or don't touch", "link_flair_richtext": [{"e": "text", "t": "Discussion"}], "subreddit_name_prefixed": "r/Python", "hidden": false, "pwls": 6, "link_flair_css_class": "discussion", "downs": 0, "thumbnail_height": null, "top_awarded_type": null, "hide_score": false, "name": "t3_1umxiti", "quarantine": false, "link_flair_text_color": "light", "upvote_ratio": 0.39, "author_flair_background_color": null, "subreddit_type": "public", "ups": 0, "total_awards_received": 0, "media_embed": {}, "thumbnail_width": null, "author_flair_template_id": null, "is_original_content": false, "user_reports": [], "secure_media": null, "is_reddit_media_domain": false, "is_meta": false, "category": null, "secure_media_embed": {}, "link_flair_text": "Discussion", "can_mod_post": false, "score": 0, "approved_by": null, "is_created_from_ads_ui": false, "author_premium": false, "thumbnail": "self", "edited": false, "author_flair_css_class": null, "author_flair_richtext": [], "gildings": {}, "content_categories": null, "is_self": true, "mod_note": null, "created": 1783133390.0, "link_flair_type": "richtext", "wls": 6, "removed_by_category": null, "banned_by": null, "author_flair_type": "text", "domain": "self.Python", "allow_live_comments": false, "selftext_html": "I have this really messy code scattered in 5 files, it s not that long abt 4000 lines.
\nadding a new feature started feeling like a pain,
\nI hate to deliver this tomorrow, and it s not meant to be scalable.
\nshould i refactor or add the features ?
\n\n
or just add the features and keep the code structure unchanged
\n
", "likes": null, "suggested_sort": null, "banned_at_utc": null, "view_count": null, "archived": false, "no_follow": true, "is_crosspostable": false, "pinned": false, "over_18": false, "all_awardings": [], "awarders": [], "media_only": false, "link_flair_template_id": "0df42996-1c5e-11ea-b1a0-0e44e1c5b731", "can_gild": false, "spoiler": false, "locked": false, "author_flair_text": null, "treatment_tags": [], "visited": false, "removed_by": null, "num_reports": null, "distinguished": null, "subreddit_id": "t5_2qh0y", "author_is_blocked": false, "mod_reason_by": null, "removal_reason": null, "link_flair_background_color": "#f50057", "id": "1umxiti", "is_robot_indexable": true, "report_reasons": null, "author": "Negative_Pay_2940", "discussion_type": null, "num_comments": 19, "send_replies": true, "contest_mode": false, "mod_reports": [], "author_patreon_flair": false, "author_flair_text_color": null, "permalink": "/r/Python/comments/1umxiti/refactor_or_dont_touch/", "stickied": false, "url": "https://www.reddit.com/r/Python/comments/1umxiti/refactor_or_dont_touch/", "subreddit_subscribers": 1493425, "created_utc": 1783133390.0, "num_crossposts": 0, "media": null, "is_video": false}}, {"kind": "t3", "data": {"approved_at_utc": null, "subreddit": "Python", "selftext": "I wrote [a practical article](https://modernpython.io/serving-a-frontend-with-fastapi-a-practical-guide/) about FastAPI's `app.frontend()` feature.\n\nThe interesting bit is that it serves static frontend build output as low-priority routes, so normal FastAPI API endpoints still win.\n\nThe article covers:\n\n* `app.frontend(\"/\", directory=\"dist\")`\n* SPA fallback with `fallback=\"index.html\"`\n* how it differs from `StaticFiles`\n* serving under a prefix with `APIRouter`\n* a complete mini dashboard example with FastAPI + vanilla JS\n\n", "author_fullname": "t2_2g9w5mkd56", "saved": false, "mod_reason_title": null, "gilded": 0, "clicked": false, "title": "FastAPI app.frontend(): serving a frontend build from the same Python app", "link_flair_richtext": [{"e": "text", "t": "News"}], "subreddit_name_prefixed": "r/Python", "hidden": false, "pwls": 6, "link_flair_css_class": "news", "downs": 0, "thumbnail_height": null, "top_awarded_type": null, "hide_score": false, "name": "t3_1uleil4", "quarantine": false, "link_flair_text_color": "light", "upvote_ratio": 0.87, "author_flair_background_color": null, "subreddit_type": "public", "ups": 43, "total_awards_received": 0, "media_embed": {}, "thumbnail_width": null, "author_flair_template_id": null, "is_original_content": false, "user_reports": [], "secure_media": null, "is_reddit_media_domain": false, "is_meta": false, "category": null, "secure_media_embed": {}, "link_flair_text": "News", "can_mod_post": false, "score": 43, "approved_by": null, "is_created_from_ads_ui": false, "author_premium": false, "thumbnail": "self", "edited": false, "author_flair_css_class": null, "author_flair_richtext": [], "gildings": {}, "post_hint": "self", "content_categories": null, "is_self": true, "mod_note": null, "created": 1782988324.0, "link_flair_type": "richtext", "wls": 6, "removed_by_category": null, "banned_by": null, "author_flair_type": "text", "domain": "self.Python", "allow_live_comments": false, "selftext_html": "I wrote a practical article about FastAPI's app.frontend() feature.
\n\n
The interesting bit is that it serves static frontend build output as low-priority routes, so normal FastAPI API endpoints still win.
\n\n
The article covers:
\n\n
\napp.frontend("/", directory="dist") \n- SPA fallback with
fallback="index.html" \n- how it differs from
StaticFiles \n- serving under a prefix with
APIRouter \n- a complete mini dashboard example with FastAPI + vanilla JS
\n
\n
", "likes": null, "suggested_sort": null, "banned_at_utc": null, "view_count": null, "archived": false, "no_follow": false, "is_crosspostable": false, "pinned": false, "over_18": false, "preview": {"images": [{"source": {"url": "https://external-preview.redd.it/W-WAtZE5DKslM0Jc7ztGVYI5ALKI9kdfdg2SO7Is-Gk.png?auto=webp&s=da9c531b534cd2ce2779c8005b7153f7f653124e", "width": 1200, "height": 800}, "resolutions": [{"url": "https://external-preview.redd.it/W-WAtZE5DKslM0Jc7ztGVYI5ALKI9kdfdg2SO7Is-Gk.png?width=108&crop=smart&auto=webp&s=8eabae27f78ffb0229c98205ef3c572e76984bf4", "width": 108, "height": 72}, {"url": "https://external-preview.redd.it/W-WAtZE5DKslM0Jc7ztGVYI5ALKI9kdfdg2SO7Is-Gk.png?width=216&crop=smart&auto=webp&s=f9e91bf257102fca1a361ceb8a0787edcffcf92c", "width": 216, "height": 144}, {"url": "https://external-preview.redd.it/W-WAtZE5DKslM0Jc7ztGVYI5ALKI9kdfdg2SO7Is-Gk.png?width=320&crop=smart&auto=webp&s=991b2400e6f7a30ba2840c5a2863a0c6b26c11b4", "width": 320, "height": 213}, {"url": "https://external-preview.redd.it/W-WAtZE5DKslM0Jc7ztGVYI5ALKI9kdfdg2SO7Is-Gk.png?width=640&crop=smart&auto=webp&s=6a2d8086326a1d4535d2dceaaf57c682c3937cc7", "width": 640, "height": 426}, {"url": "https://external-preview.redd.it/W-WAtZE5DKslM0Jc7ztGVYI5ALKI9kdfdg2SO7Is-Gk.png?width=960&crop=smart&auto=webp&s=da8e0ad5c59939e0d9056a5c02da7a9c0e67fae0", "width": 960, "height": 640}, {"url": "https://external-preview.redd.it/W-WAtZE5DKslM0Jc7ztGVYI5ALKI9kdfdg2SO7Is-Gk.png?width=1080&crop=smart&auto=webp&s=cdb6a73a729564d7890372379f04bc7928ca2e28", "width": 1080, "height": 720}], "variants": {}, "id": "W-WAtZE5DKslM0Jc7ztGVYI5ALKI9kdfdg2SO7Is-Gk"}], "enabled": false}, "all_awardings": [], "awarders": [], "media_only": false, "link_flair_template_id": "0ad780a0-1c5e-11ea-978c-0ee7bacb2bff", "can_gild": false, "spoiler": false, "locked": false, "author_flair_text": null, "treatment_tags": [], "visited": false, "removed_by": null, "num_reports": null, "distinguished": null, "subreddit_id": "t5_2qh0y", "author_is_blocked": false, "mod_reason_by": null, "removal_reason": null, "link_flair_background_color": "#7193ff", "id": "1uleil4", "is_robot_indexable": true, "report_reasons": null, "author": "ModernPython", "discussion_type": null, "num_comments": 13, "send_replies": true, "contest_mode": false, "mod_reports": [], "author_patreon_flair": false, "author_flair_text_color": null, "permalink": "/r/Python/comments/1uleil4/fastapi_appfrontend_serving_a_frontend_build_from/", "stickied": false, "url": "https://www.reddit.com/r/Python/comments/1uleil4/fastapi_appfrontend_serving_a_frontend_build_from/", "subreddit_subscribers": 1493425, "created_utc": 1782988324.0, "num_crossposts": 0, "media": null, "is_video": false}}, {"kind": "t3", "data": {"approved_at_utc": null, "subreddit": "Python", "selftext": "# Weekly Thread: Meta Discussions and Free Talk Friday \ud83c\udf99\ufe0f\n\nWelcome to Free Talk Friday on /r/Python! This is the place to discuss the r/Python community (meta discussions), Python news, projects, or anything else Python-related!\n\n## How it Works:\n\n1. **Open Mic**: Share your thoughts, questions, or anything you'd like related to Python or the community.\n2. **Community Pulse**: Discuss what you feel is working well or what could be improved in the /r/python community.\n3. **News & Updates**: Keep up-to-date with the latest in Python and share any news you find interesting.\n\n## Guidelines:\n\n* All topics should be related to Python or the /r/python community.\n* Be respectful and follow Reddit's [Code of Conduct](https://www.redditinc.com/policies/content-policy).\n\n## Example Topics:\n\n1. **New Python Release**: What do you think about the new features in Python 3.11?\n2. **Community Events**: Any Python meetups or webinars coming up?\n3. **Learning Resources**: Found a great Python tutorial? Share it here!\n4. **Job Market**: How has Python impacted your career?\n5. **Hot Takes**: Got a controversial Python opinion? Let's hear it!\n6. **Community Ideas**: Something you'd like to see us do? tell us.\n\nLet's keep the conversation going. Happy discussing! \ud83c\udf1f", "author_fullname": "t2_6l4z3", "saved": false, "mod_reason_title": null, "gilded": 0, "clicked": false, "title": "Friday Daily Thread: r/Python Meta and Free-Talk Fridays", "link_flair_richtext": [{"a": ":pythonLogo:", "e": "emoji", "u": "https://emoji.redditmedia.com/8yxdpg6xxnr71_t5_2qh0y/pythonLogo"}, {"e": "text", "t": " Daily Thread"}], "subreddit_name_prefixed": "r/Python", "hidden": false, "pwls": 6, "link_flair_css_class": "daily-thread", "downs": 0, "thumbnail_height": null, "top_awarded_type": null, "hide_score": false, "name": "t3_1ulyrvh", "quarantine": false, "link_flair_text_color": "light", "upvote_ratio": 0.86, "author_flair_background_color": null, "subreddit_type": "public", "ups": 5, "total_awards_received": 0, "media_embed": {}, "thumbnail_width": null, "author_flair_template_id": null, "is_original_content": false, "user_reports": [], "secure_media": null, "is_reddit_media_domain": false, "is_meta": false, "category": null, "secure_media_embed": {}, "link_flair_text": ":pythonLogo: Daily Thread", "can_mod_post": false, "score": 5, "approved_by": null, "is_created_from_ads_ui": false, "author_premium": true, "thumbnail": "self", "edited": false, "author_flair_css_class": null, "author_flair_richtext": [], "gildings": {}, "content_categories": null, "is_self": true, "mod_note": null, "created": 1783036824.0, "link_flair_type": "richtext", "wls": 6, "removed_by_category": null, "banned_by": null, "author_flair_type": "text", "domain": "self.Python", "allow_live_comments": false, "selftext_html": "Weekly Thread: Meta Discussions and Free Talk Friday \ud83c\udf99\ufe0f
\n\n
Welcome to Free Talk Friday on /r/Python! This is the place to discuss the r/Python community (meta discussions), Python news, projects, or anything else Python-related!
\n\n
How it Works:
\n\n
\n- Open Mic: Share your thoughts, questions, or anything you'd like related to Python or the community.
\n- Community Pulse: Discuss what you feel is working well or what could be improved in the /r/python community.
\n- News & Updates: Keep up-to-date with the latest in Python and share any news you find interesting.
\n
\n\n
Guidelines:
\n\n
\n- All topics should be related to Python or the /r/python community.
\n- Be respectful and follow Reddit's Code of Conduct.
\n
\n\n
Example Topics:
\n\n
\n- New Python Release: What do you think about the new features in Python 3.11?
\n- Community Events: Any Python meetups or webinars coming up?
\n- Learning Resources: Found a great Python tutorial? Share it here!
\n- Job Market: How has Python impacted your career?
\n- Hot Takes: Got a controversial Python opinion? Let's hear it!
\n- Community Ideas: Something you'd like to see us do? tell us.
\n
\n\n
Let's keep the conversation going. Happy discussing! \ud83c\udf1f
\n
", "likes": null, "suggested_sort": null, "banned_at_utc": null, "view_count": null, "archived": false, "no_follow": false, "is_crosspostable": false, "pinned": false, "over_18": false, "all_awardings": [], "awarders": [], "media_only": false, "link_flair_template_id": "6c024934-de3f-11ea-a05a-0ea86b2be9a1", "can_gild": false, "spoiler": false, "locked": false, "author_flair_text": null, "treatment_tags": [], "visited": false, "removed_by": null, "num_reports": null, "distinguished": null, "subreddit_id": "t5_2qh0y", "author_is_blocked": false, "mod_reason_by": null, "removal_reason": null, "link_flair_background_color": "#00a6a5", "id": "1ulyrvh", "is_robot_indexable": true, "report_reasons": null, "author": "AutoModerator", "discussion_type": null, "num_comments": 2, "send_replies": true, "contest_mode": false, "mod_reports": [], "author_patreon_flair": false, "author_flair_text_color": null, "permalink": "/r/Python/comments/1ulyrvh/friday_daily_thread_rpython_meta_and_freetalk/", "stickied": false, "url": "https://www.reddit.com/r/Python/comments/1ulyrvh/friday_daily_thread_rpython_meta_and_freetalk/", "subreddit_subscribers": 1493425, "created_utc": 1783036824.0, "num_crossposts": 0, "media": null, "is_video": false}}, {"kind": "t3", "data": {"approved_at_utc": null, "subreddit": "Python", "selftext": "Running Celery on AWS ECS can be trickier than it seems if you want to avoid lost tasks and ensure all work is completed. Especially if you're frequently deploying to production and using autoscaling.\n\nThere are two main components for reliable processing:\n- Celery configuration updates\n- Structuring tasks\n\nFor Celery, you should update the following settings:\n- task_acks_late -> True: To treat tasks as successfully processed only after processing. Otherwise, tasks are not retried.\n- task_reject_on_worker_lost -> True: To ensure tasks are retried if workers die for any reason (e.g., warm shutdown + SIGKILL).\n- worker_prefetch_multiplier -> 1: To avoid unnecessarily delayed tasks.\n- broker_connection_retry_on_startup -> True: To make startups more reliable.\n- broker_transport_options -> {\"confirm_publish\": True}: To avoid unsubmitted tasks due to message transport issues.\n- Make sure exponential retries are enabled. This way, you ensure that tasks are retried in the event of an interruption.\n\nFor structuring tasks, use the following two approaches:\n- Batching: Instead of doing all the work at once, you split the work into batches. e.g., Process 1000 users, then submit the next job to process the next 1000 users.\n- Fan out: You can split the work between a \"scheduler\" task and \"execution\" tasks. e.g., One task to list all the users and submit email sending tasks, another task to actually send an email for the selected user\n\nThe same applies to other similar services, such as Heroku and Azure App Containers, which use short grace periods during rolling deployments and downscaling.\n\nYou can read a more elaborate tutorial here: https://jangiacomelli.com/blog/celery-on-aws-ecs/\n", "author_fullname": "t2_5uvfj9zf", "saved": false, "mod_reason_title": null, "gilded": 0, "clicked": false, "title": "Celery on AWS ECS - prevent lost tasks and ensure the work is always done", "link_flair_richtext": [{"e": "text", "t": "Tutorial"}], "subreddit_name_prefixed": "r/Python", "hidden": false, "pwls": 6, "link_flair_css_class": "tutorial", "downs": 0, "thumbnail_height": null, "top_awarded_type": null, "hide_score": false, "name": "t3_1uleyez", "quarantine": false, "link_flair_text_color": "dark", "upvote_ratio": 0.82, "author_flair_background_color": null, "subreddit_type": "public", "ups": 31, "total_awards_received": 0, "media_embed": {}, "thumbnail_width": null, "author_flair_template_id": null, "is_original_content": false, "user_reports": [], "secure_media": null, "is_reddit_media_domain": false, "is_meta": false, "category": null, "secure_media_embed": {}, "link_flair_text": "Tutorial", "can_mod_post": false, "score": 31, "approved_by": null, "is_created_from_ads_ui": false, "author_premium": false, "thumbnail": "self", "edited": false, "author_flair_css_class": null, "author_flair_richtext": [], "gildings": {}, "post_hint": "self", "content_categories": null, "is_self": true, "mod_note": null, "created": 1782989774.0, "link_flair_type": "richtext", "wls": 6, "removed_by_category": null, "banned_by": null, "author_flair_type": "text", "domain": "self.Python", "allow_live_comments": false, "selftext_html": "Running Celery on AWS ECS can be trickier than it seems if you want to avoid lost tasks and ensure all work is completed. Especially if you're frequently deploying to production and using autoscaling.
\n\n
There are two main components for reliable processing:\n- Celery configuration updates\n- Structuring tasks
\n\n
For Celery, you should update the following settings:\n- task_acks_late -> True: To treat tasks as successfully processed only after processing. Otherwise, tasks are not retried.\n- task_reject_on_worker_lost -> True: To ensure tasks are retried if workers die for any reason (e.g., warm shutdown + SIGKILL).\n- worker_prefetch_multiplier -> 1: To avoid unnecessarily delayed tasks.\n- broker_connection_retry_on_startup -> True: To make startups more reliable.\n- broker_transport_options -> {"confirm_publish": True}: To avoid unsubmitted tasks due to message transport issues.\n- Make sure exponential retries are enabled. This way, you ensure that tasks are retried in the event of an interruption.
\n\n
For structuring tasks, use the following two approaches:\n- Batching: Instead of doing all the work at once, you split the work into batches. e.g., Process 1000 users, then submit the next job to process the next 1000 users.\n- Fan out: You can split the work between a "scheduler" task and "execution" tasks. e.g., One task to list all the users and submit email sending tasks, another task to actually send an email for the selected user
\n\n
The same applies to other similar services, such as Heroku and Azure App Containers, which use short grace periods during rolling deployments and downscaling.
\n\n
You can read a more elaborate tutorial here: https://jangiacomelli.com/blog/celery-on-aws-ecs/
\n
", "likes": null, "suggested_sort": null, "banned_at_utc": null, "view_count": null, "archived": false, "no_follow": false, "is_crosspostable": false, "pinned": false, "over_18": false, "preview": {"images": [{"source": {"url": "https://external-preview.redd.it/mw6L6MkeGzNGpfloYiy2lOpj4iblwUcNtBT7-YQogdc.png?auto=webp&s=4476a039806bd30ea3113713247eeb17736e2a04", "width": 1200, "height": 630}, "resolutions": [{"url": "https://external-preview.redd.it/mw6L6MkeGzNGpfloYiy2lOpj4iblwUcNtBT7-YQogdc.png?width=108&crop=smart&auto=webp&s=e004a2cd64b3e00a25e30cf9334f09216b2013ca", "width": 108, "height": 56}, {"url": "https://external-preview.redd.it/mw6L6MkeGzNGpfloYiy2lOpj4iblwUcNtBT7-YQogdc.png?width=216&crop=smart&auto=webp&s=f8b05628d10153dae539aa93e3d9672de283ce16", "width": 216, "height": 113}, {"url": "https://external-preview.redd.it/mw6L6MkeGzNGpfloYiy2lOpj4iblwUcNtBT7-YQogdc.png?width=320&crop=smart&auto=webp&s=008f5cc3e3a7b2997f9efce55cdfd4f4b761911a", "width": 320, "height": 168}, {"url": "https://external-preview.redd.it/mw6L6MkeGzNGpfloYiy2lOpj4iblwUcNtBT7-YQogdc.png?width=640&crop=smart&auto=webp&s=16910f1218cbb38fa5649ceec04feb8624bca35e", "width": 640, "height": 336}, {"url": "https://external-preview.redd.it/mw6L6MkeGzNGpfloYiy2lOpj4iblwUcNtBT7-YQogdc.png?width=960&crop=smart&auto=webp&s=5dac9bf645784e560b4aefd42968c8377f26656f", "width": 960, "height": 504}, {"url": "https://external-preview.redd.it/mw6L6MkeGzNGpfloYiy2lOpj4iblwUcNtBT7-YQogdc.png?width=1080&crop=smart&auto=webp&s=904e0e68111e9dafe766adb0b7d95fc53e94668b", "width": 1080, "height": 567}], "variants": {}, "id": "mw6L6MkeGzNGpfloYiy2lOpj4iblwUcNtBT7-YQogdc"}], "enabled": false}, "all_awardings": [], "awarders": [], "media_only": false, "link_flair_template_id": "7987a74c-04d8-11eb-84ca-0e0ac8b5a78f", "can_gild": false, "spoiler": false, "locked": false, "author_flair_text": null, "treatment_tags": [], "visited": false, "removed_by": null, "num_reports": null, "distinguished": null, "subreddit_id": "t5_2qh0y", "author_is_blocked": false, "mod_reason_by": null, "removal_reason": null, "link_flair_background_color": "#dadada", "id": "1uleyez", "is_robot_indexable": true, "report_reasons": null, "author": "JanGiacomelli", "discussion_type": null, "num_comments": 13, "send_replies": true, "contest_mode": false, "mod_reports": [], "author_patreon_flair": false, "author_flair_text_color": null, "permalink": "/r/Python/comments/1uleyez/celery_on_aws_ecs_prevent_lost_tasks_and_ensure/", "stickied": false, "url": "https://www.reddit.com/r/Python/comments/1uleyez/celery_on_aws_ecs_prevent_lost_tasks_and_ensure/", "subreddit_subscribers": 1493425, "created_utc": 1782989774.0, "num_crossposts": 0, "media": null, "is_video": false}}, {"kind": "t3", "data": {"approved_at_utc": null, "subreddit": "Python", "selftext": "# Weekly Thread: Professional Use, Jobs, and Education \ud83c\udfe2\n\nWelcome to this week's discussion on Python in the professional world! This is your spot to talk about job hunting, career growth, and educational resources in Python. Please note, this thread is **not for recruitment**.\n\n---\n\n## How it Works:\n\n1. **Career Talk**: Discuss using Python in your job, or the job market for Python roles.\n2. **Education Q&A**: Ask or answer questions about Python courses, certifications, and educational resources.\n3. **Workplace Chat**: Share your experiences, challenges, or success stories about using Python professionally.\n\n---\n\n## Guidelines:\n\n- This thread is **not for recruitment**. For job postings, please see r/PythonJobs or the recruitment thread in the sidebar.\n- Keep discussions relevant to Python in the professional and educational context.\n \n---\n\n## Example Topics:\n\n1. **Career Paths**: What kinds of roles are out there for Python developers?\n2. **Certifications**: Are Python certifications worth it?\n3. **Course Recommendations**: Any good advanced Python courses to recommend?\n4. **Workplace Tools**: What Python libraries are indispensable in your professional work?\n5. **Interview Tips**: What types of Python questions are commonly asked in interviews?\n\n---\n\nLet's help each other grow in our careers and education. Happy discussing! \ud83c\udf1f", "author_fullname": "t2_6l4z3", "saved": false, "mod_reason_title": null, "gilded": 0, "clicked": false, "title": "Thursday Daily Thread: Python Careers, Courses, and Furthering Education!", "link_flair_richtext": [{"a": ":pythonLogo:", "e": "emoji", "u": "https://emoji.redditmedia.com/8yxdpg6xxnr71_t5_2qh0y/pythonLogo"}, {"e": "text", "t": " Daily Thread"}], "subreddit_name_prefixed": "r/Python", "hidden": false, "pwls": 6, "link_flair_css_class": "daily-thread", "downs": 0, "thumbnail_height": null, "top_awarded_type": null, "hide_score": false, "name": "t3_1ul2dky", "quarantine": false, "link_flair_text_color": "light", "upvote_ratio": 0.73, "author_flair_background_color": null, "subreddit_type": "public", "ups": 8, "total_awards_received": 0, "media_embed": {}, "thumbnail_width": null, "author_flair_template_id": null, "is_original_content": false, "user_reports": [], "secure_media": null, "is_reddit_media_domain": false, "is_meta": false, "category": null, "secure_media_embed": {}, "link_flair_text": ":pythonLogo: Daily Thread", "can_mod_post": false, "score": 8, "approved_by": null, "is_created_from_ads_ui": false, "author_premium": true, "thumbnail": "self", "edited": false, "author_flair_css_class": null, "author_flair_richtext": [], "gildings": {}, "content_categories": null, "is_self": true, "mod_note": null, "created": 1782950428.0, "link_flair_type": "richtext", "wls": 6, "removed_by_category": null, "banned_by": null, "author_flair_type": "text", "domain": "self.Python", "allow_live_comments": false, "selftext_html": "Weekly Thread: Professional Use, Jobs, and Education \ud83c\udfe2
\n\n
Welcome to this week's discussion on Python in the professional world! This is your spot to talk about job hunting, career growth, and educational resources in Python. Please note, this thread is not for recruitment.
\n\n
\n\n
How it Works:
\n\n
\n- Career Talk: Discuss using Python in your job, or the job market for Python roles.
\n- Education Q&A: Ask or answer questions about Python courses, certifications, and educational resources.
\n- Workplace Chat: Share your experiences, challenges, or success stories about using Python professionally.
\n
\n\n
\n\n
Guidelines:
\n\n
\n- This thread is not for recruitment. For job postings, please see r/PythonJobs or the recruitment thread in the sidebar.
\n- Keep discussions relevant to Python in the professional and educational context.
\n
\n\n
\n\n
Example Topics:
\n\n
\n- Career Paths: What kinds of roles are out there for Python developers?
\n- Certifications: Are Python certifications worth it?
\n- Course Recommendations: Any good advanced Python courses to recommend?
\n- Workplace Tools: What Python libraries are indispensable in your professional work?
\n- Interview Tips: What types of Python questions are commonly asked in interviews?
\n
\n\n
\n\n
Let's help each other grow in our careers and education. Happy discussing! \ud83c\udf1f
\n
", "likes": null, "suggested_sort": null, "banned_at_utc": null, "view_count": null, "archived": false, "no_follow": false, "is_crosspostable": false, "pinned": false, "over_18": false, "all_awardings": [], "awarders": [], "media_only": false, "link_flair_template_id": "6c024934-de3f-11ea-a05a-0ea86b2be9a1", "can_gild": false, "spoiler": false, "locked": false, "author_flair_text": null, "treatment_tags": [], "visited": false, "removed_by": null, "num_reports": null, "distinguished": "moderator", "subreddit_id": "t5_2qh0y", "author_is_blocked": false, "mod_reason_by": null, "removal_reason": null, "link_flair_background_color": "#00a6a5", "id": "1ul2dky", "is_robot_indexable": true, "report_reasons": null, "author": "AutoModerator", "discussion_type": null, "num_comments": 2, "send_replies": false, "contest_mode": false, "mod_reports": [], "author_patreon_flair": false, "author_flair_text_color": null, "permalink": "/r/Python/comments/1ul2dky/thursday_daily_thread_python_careers_courses_and/", "stickied": false, "url": "https://www.reddit.com/r/Python/comments/1ul2dky/thursday_daily_thread_python_careers_courses_and/", "subreddit_subscribers": 1493425, "created_utc": 1782950428.0, "num_crossposts": 0, "media": null, "is_video": false}}, {"kind": "t3", "data": {"approved_at_utc": null, "subreddit": "Python", "selftext": "A tip that's saved us a lot of boilerplate across our Python stack (Litestar, and our document-extraction tooling): stop decoding JSON into `dict[str, Any]` and casting/`.get()`-ing your way through it. Decode straight into your declared type.\n\n`msgspec` validates and decodes directly into your type at C speed. Quick comparison of the usual options on the same payload:\n\n- `json.loads` / `orjson.loads` -> `dict[str, Any]` (cast and pray; orjson just faster)\n- `pydantic` TypeAdapter(...).validate_json -> your model, validated + rich, but heavier\n- `msgspec.json.decode(raw, type=T)` -> your type, validated, C-fast\n\npydantic does far more and its Rust core is fast; for model-heavy code it's still my default. But on hot paths where you just need decode-into-a-struct, a C decoder going straight to the type is hard to beat.\n\nWith PEP 695 generics the whole (de)serialization layer collapses to one function:\n\n```python\ndef deserialize[T](raw: bytes, t: type[T]) -> T:\n return msgspec.json.decode(raw, type=t, strict=False)\n\ndeserialize(raw, Grant) # -> Grant\ndeserialize(raw, list[Grant]) # -> list[Grant]\n```\n\nWe landed on this while building Litestar (msgspec is a big reason it's fast) and reuse it across everything now. How do you handle hot-path decoding \u2014 msgspec, orjson + manual validation, or full pydantic?", "author_fullname": "t2_9t15mit", "saved": false, "mod_reason_title": null, "gilded": 0, "clicked": false, "title": "Tip: use msgspec for JSON decoding \u2014 it decodes straight into your type at C speed", "link_flair_richtext": [{"e": "text", "t": "Discussion"}], "subreddit_name_prefixed": "r/Python", "hidden": false, "pwls": 6, "link_flair_css_class": "discussion", "downs": 0, "thumbnail_height": null, "top_awarded_type": null, "hide_score": false, "name": "t3_1ukh3q5", "quarantine": false, "link_flair_text_color": "light", "upvote_ratio": 0.87, "author_flair_background_color": "transparent", "subreddit_type": "public", "ups": 106, "total_awards_received": 0, "media_embed": {}, "thumbnail_width": null, "author_flair_template_id": "67d01c9c-537b-11ee-b0d0-7225f76af176", "is_original_content": false, "user_reports": [], "secure_media": null, "is_reddit_media_domain": false, "is_meta": false, "category": null, "secure_media_embed": {}, "link_flair_text": "Discussion", "can_mod_post": false, "score": 106, "approved_by": null, "is_created_from_ads_ui": false, "author_premium": false, "thumbnail": "self", "edited": false, "author_flair_css_class": null, "author_flair_richtext": [{"e": "text", "t": "Pythonista"}], "gildings": {}, "content_categories": null, "is_self": true, "mod_note": null, "created": 1782899155.0, "link_flair_type": "richtext", "wls": 6, "removed_by_category": null, "banned_by": null, "author_flair_type": "richtext", "domain": "self.Python", "allow_live_comments": false, "selftext_html": "A tip that's saved us a lot of boilerplate across our Python stack (Litestar, and our document-extraction tooling): stop decoding JSON into dict[str, Any] and casting/.get()-ing your way through it. Decode straight into your declared type.
\n\n
msgspec validates and decodes directly into your type at C speed. Quick comparison of the usual options on the same payload:
\n\n
\njson.loads / orjson.loads -> dict[str, Any] (cast and pray; orjson just faster) \npydantic TypeAdapter(...).validate_json -> your model, validated + rich, but heavier \nmsgspec.json.decode(raw, type=T) -> your type, validated, C-fast \n
\n\n
pydantic does far more and its Rust core is fast; for model-heavy code it's still my default. But on hot paths where you just need decode-into-a-struct, a C decoder going straight to the type is hard to beat.
\n\n
With PEP 695 generics the whole (de)serialization layer collapses to one function:
\n\n
```python\ndef deserialize[T](raw: bytes, t: type[T]) -> T:\n return msgspec.json.decode(raw, type=t, strict=False)
\n\n
deserialize(raw, Grant) # -> Grant\ndeserialize(raw, list[Grant]) # -> list[Grant]\n```
\n\n
We landed on this while building Litestar (msgspec is a big reason it's fast) and reuse it across everything now. How do you handle hot-path decoding \u2014 msgspec, orjson + manual validation, or full pydantic?
\n
", "likes": null, "suggested_sort": null, "banned_at_utc": null, "view_count": null, "archived": false, "no_follow": false, "is_crosspostable": false, "pinned": false, "over_18": false, "all_awardings": [], "awarders": [], "media_only": false, "link_flair_template_id": "0df42996-1c5e-11ea-b1a0-0e44e1c5b731", "can_gild": false, "spoiler": false, "locked": false, "author_flair_text": "Pythonista", "treatment_tags": [], "visited": false, "removed_by": null, "num_reports": null, "distinguished": null, "subreddit_id": "t5_2qh0y", "author_is_blocked": false, "mod_reason_by": null, "removal_reason": null, "link_flair_background_color": "#f50057", "id": "1ukh3q5", "is_robot_indexable": true, "report_reasons": null, "author": "Goldziher", "discussion_type": null, "num_comments": 26, "send_replies": true, "contest_mode": false, "mod_reports": [], "author_patreon_flair": false, "author_flair_text_color": "dark", "permalink": "/r/Python/comments/1ukh3q5/tip_use_msgspec_for_json_decoding_it_decodes/", "stickied": false, "url": "https://www.reddit.com/r/Python/comments/1ukh3q5/tip_use_msgspec_for_json_decoding_it_decodes/", "subreddit_subscribers": 1493425, "created_utc": 1782899155.0, "num_crossposts": 0, "media": null, "is_video": false}}, {"kind": "t3", "data": {"approved_at_utc": null, "subreddit": "Python", "selftext": "I\u2019ve been using the Pythonista IDE by Ole Zorn for over 10 years and I\u2019m just amazed at how consistently good it is. It doesn\u2019t have the latest greatest features but I still use it almost daily. Works with IOS Shortcuts as well. This would be a good one to add to the Wiki.", "author_fullname": "t2_q6jo6", "saved": false, "mod_reason_title": null, "gilded": 0, "clicked": false, "title": "Pythonista IDE for IOS should be added to the Wiki", "link_flair_richtext": [{"e": "text", "t": "Discussion"}], "subreddit_name_prefixed": "r/Python", "hidden": false, "pwls": 6, "link_flair_css_class": "discussion", "downs": 0, "thumbnail_height": null, "top_awarded_type": null, "hide_score": false, "name": "t3_1ul4j9h", "quarantine": false, "link_flair_text_color": "light", "upvote_ratio": 0.65, "author_flair_background_color": null, "subreddit_type": "public", "ups": 5, "total_awards_received": 0, "media_embed": {}, "thumbnail_width": null, "author_flair_template_id": null, "is_original_content": false, "user_reports": [], "secure_media": null, "is_reddit_media_domain": false, "is_meta": false, "category": null, "secure_media_embed": {}, "link_flair_text": "Discussion", "can_mod_post": false, "score": 5, "approved_by": null, "is_created_from_ads_ui": false, "author_premium": false, "thumbnail": "self", "edited": false, "author_flair_css_class": null, "author_flair_richtext": [], "gildings": {}, "content_categories": null, "is_self": true, "mod_note": null, "created": 1782956290.0, "link_flair_type": "richtext", "wls": 6, "removed_by_category": null, "banned_by": null, "author_flair_type": "text", "domain": "self.Python", "allow_live_comments": false, "selftext_html": "I\u2019ve been using the Pythonista IDE by Ole Zorn for over 10 years and I\u2019m just amazed at how consistently good it is. It doesn\u2019t have the latest greatest features but I still use it almost daily. Works with IOS Shortcuts as well. This would be a good one to add to the Wiki.
\n
", "likes": null, "suggested_sort": null, "banned_at_utc": null, "view_count": null, "archived": false, "no_follow": false, "is_crosspostable": false, "pinned": false, "over_18": false, "all_awardings": [], "awarders": [], "media_only": false, "link_flair_template_id": "0df42996-1c5e-11ea-b1a0-0e44e1c5b731", "can_gild": false, "spoiler": false, "locked": false, "author_flair_text": null, "treatment_tags": [], "visited": false, "removed_by": null, "num_reports": null, "distinguished": null, "subreddit_id": "t5_2qh0y", "author_is_blocked": false, "mod_reason_by": null, "removal_reason": null, "link_flair_background_color": "#f50057", "id": "1ul4j9h", "is_robot_indexable": true, "report_reasons": null, "author": "TutorialDoctor", "discussion_type": null, "num_comments": 8, "send_replies": true, "contest_mode": false, "mod_reports": [], "author_patreon_flair": false, "author_flair_text_color": null, "permalink": "/r/Python/comments/1ul4j9h/pythonista_ide_for_ios_should_be_added_to_the_wiki/", "stickied": false, "url": "https://www.reddit.com/r/Python/comments/1ul4j9h/pythonista_ide_for_ios_should_be_added_to_the_wiki/", "subreddit_subscribers": 1493425, "created_utc": 1782956290.0, "num_crossposts": 0, "media": null, "is_video": false}}, {"kind": "t3", "data": {"approved_at_utc": null, "subreddit": "Python", "selftext": "**The clustering problem with correlated signals**\n\nMy system scores ~40 macro signals (Fed funds rate, yield curve, M2, insider buying, short interest, etc.) and generates a composite \"confluence score\" for a given ticker. The naive approach is to just average the signals. Problem: many signals are correlated \u2014 yield curve and credit spreads move together, insider buying and short interest are often inversely related. Averaging them inflates apparent confidence.\n\nFix I landed on: pairwise Pearson correlation matrix using pandas + numpy on 3 years of weekly signal history. Then `scipy.cluster.hierarchy.linkage` with single-linkage at a 0.6 threshold groups correlated signals into clusters. Each cluster gets one vote, weighted by the cluster member with the best out-of-sample Sharpe ratio on that ticker's 60-day forward returns.\n\n**Streamlit caching gotchas**\n\n`@st.cache_data` is great but has a subtle memory issue: it keeps ALL cached versions until max_entries is hit. For a function that fetches 40 signals with 5 time-period variations, you can end up caching 200+ DataFrames. Added `max_entries=1` to the main signals cache \u2014 memory dropped from ~1.1GB to ~200MB under concurrent load.\n\nAlso: calling `ThreadPoolExecutor` inside a cached function is fine for pure data fetching. But if the cached function spawns threads that themselves call other cached functions, you can hit Streamlit's session state lock. Solution: only parallelize at the outermost uncached layer.\n\n**SEC EDGAR Form 4 XML parsing**\n\nEDGAR serves Form 4 filings as XML, but namespace handling is inconsistent across filings. Some have explicit xmlns declarations, some don't. I strip namespaces with a regex before parsing:\n\n xml_str = re.sub(r'\\s*xmlns[^\"]*\"[^\"]*\"', '', raw_xml)\n tree = ET.fromstring(xml_str)\n\nFor insider cluster detection (flagging when 2+ insiders buy within 21 days), I group by issuer CIK, filter for `transactionCode == 'P'` (open-market purchase), then use a rolling window on sorted transaction dates.\n\n**SQLAlchemy Core schema**\n\nUsing SQLAlchemy Core (not ORM) for the main tables: users, signal_snapshots, watchlist_items, alerts. One thing I'm glad I did: a single DATABASE_URL env var that switches between Postgres (prod) and SQLite (local dev). Same schema DDL works for both \u2014 keeps the local dev loop fast.\n\nHappy to answer questions on any of the above.", "author_fullname": "t2_d021y6fm", "saved": false, "mod_reason_title": null, "gilded": 0, "clicked": false, "title": "Learned a lot building a macro signal scoring system in Python - sharing architecture decisions", "link_flair_richtext": [{"e": "text", "t": "Discussion"}], "subreddit_name_prefixed": "r/Python", "hidden": false, "pwls": 6, "link_flair_css_class": "discussion", "downs": 0, "thumbnail_height": null, "top_awarded_type": null, "hide_score": false, "name": "t3_1ul7qiv", "quarantine": false, "link_flair_text_color": "light", "upvote_ratio": 0.56, "author_flair_background_color": null, "subreddit_type": "public", "ups": 1, "total_awards_received": 0, "media_embed": {}, "thumbnail_width": null, "author_flair_template_id": null, "is_original_content": false, "user_reports": [], "secure_media": null, "is_reddit_media_domain": false, "is_meta": false, "category": null, "secure_media_embed": {}, "link_flair_text": "Discussion", "can_mod_post": false, "score": 1, "approved_by": null, "is_created_from_ads_ui": false, "author_premium": false, "thumbnail": "self", "edited": false, "author_flair_css_class": null, "author_flair_richtext": [], "gildings": {}, "content_categories": null, "is_self": true, "mod_note": null, "created": 1782965413.0, "link_flair_type": "richtext", "wls": 6, "removed_by_category": null, "banned_by": null, "author_flair_type": "text", "domain": "self.Python", "allow_live_comments": false, "selftext_html": "The clustering problem with correlated signals
\n\n
My system scores ~40 macro signals (Fed funds rate, yield curve, M2, insider buying, short interest, etc.) and generates a composite "confluence score" for a given ticker. The naive approach is to just average the signals. Problem: many signals are correlated \u2014 yield curve and credit spreads move together, insider buying and short interest are often inversely related. Averaging them inflates apparent confidence.
\n\n
Fix I landed on: pairwise Pearson correlation matrix using pandas + numpy on 3 years of weekly signal history. Then scipy.cluster.hierarchy.linkage with single-linkage at a 0.6 threshold groups correlated signals into clusters. Each cluster gets one vote, weighted by the cluster member with the best out-of-sample Sharpe ratio on that ticker's 60-day forward returns.
\n\n
Streamlit caching gotchas
\n\n
@st.cache_data is great but has a subtle memory issue: it keeps ALL cached versions until max_entries is hit. For a function that fetches 40 signals with 5 time-period variations, you can end up caching 200+ DataFrames. Added max_entries=1 to the main signals cache \u2014 memory dropped from ~1.1GB to ~200MB under concurrent load.
\n\n
Also: calling ThreadPoolExecutor inside a cached function is fine for pure data fetching. But if the cached function spawns threads that themselves call other cached functions, you can hit Streamlit's session state lock. Solution: only parallelize at the outermost uncached layer.
\n\n
SEC EDGAR Form 4 XML parsing
\n\n
EDGAR serves Form 4 filings as XML, but namespace handling is inconsistent across filings. Some have explicit xmlns declarations, some don't. I strip namespaces with a regex before parsing:
\n\n
xml_str = re.sub(r'\\s*xmlns[^"]*"[^"]*"', '', raw_xml)\ntree = ET.fromstring(xml_str)\n
\n\n
For insider cluster detection (flagging when 2+ insiders buy within 21 days), I group by issuer CIK, filter for transactionCode == 'P' (open-market purchase), then use a rolling window on sorted transaction dates.
\n\n
SQLAlchemy Core schema
\n\n
Using SQLAlchemy Core (not ORM) for the main tables: users, signal_snapshots, watchlist_items, alerts. One thing I'm glad I did: a single DATABASE_URL env var that switches between Postgres (prod) and SQLite (local dev). Same schema DDL works for both \u2014 keeps the local dev loop fast.
\n\n
Happy to answer questions on any of the above.
\n
", "likes": null, "suggested_sort": null, "banned_at_utc": null, "view_count": null, "archived": false, "no_follow": true, "is_crosspostable": false, "pinned": false, "over_18": false, "all_awardings": [], "awarders": [], "media_only": false, "link_flair_template_id": "0df42996-1c5e-11ea-b1a0-0e44e1c5b731", "can_gild": false, "spoiler": false, "locked": false, "author_flair_text": null, "treatment_tags": [], "visited": false, "removed_by": null, "num_reports": null, "distinguished": null, "subreddit_id": "t5_2qh0y", "author_is_blocked": false, "mod_reason_by": null, "removal_reason": null, "link_flair_background_color": "#f50057", "id": "1ul7qiv", "is_robot_indexable": true, "report_reasons": null, "author": "Historical_Ad9654", "discussion_type": null, "num_comments": 2, "send_replies": true, "contest_mode": false, "mod_reports": [], "author_patreon_flair": false, "author_flair_text_color": null, "permalink": "/r/Python/comments/1ul7qiv/learned_a_lot_building_a_macro_signal_scoring/", "stickied": false, "url": "https://www.reddit.com/r/Python/comments/1ul7qiv/learned_a_lot_building_a_macro_signal_scoring/", "subreddit_subscribers": 1493425, "created_utc": 1782965413.0, "num_crossposts": 0, "media": null, "is_video": false}}, {"kind": "t3", "data": {"approved_at_utc": null, "subreddit": "Python", "selftext": "I saw one yesterday during an interview and it really confused me at first since the feature has been deprecated for so long.\n\n \nAre there still code bases out there running Python 2? I used Python 3.8 at my last job and that made me feel like a dinosaur. ", "author_fullname": "t2_1q305nm7", "saved": false, "mod_reason_title": null, "gilded": 0, "clicked": false, "title": "When's the last time you saw Python 2 Super() syntax?", "link_flair_richtext": [{"e": "text", "t": "Discussion"}], "subreddit_name_prefixed": "r/Python", "hidden": false, "pwls": 6, "link_flair_css_class": "discussion", "downs": 0, "thumbnail_height": null, "top_awarded_type": null, "hide_score": false, "name": "t3_1uk3ym6", "quarantine": false, "link_flair_text_color": "light", "upvote_ratio": 0.87, "author_flair_background_color": null, "subreddit_type": "public", "ups": 103, "total_awards_received": 0, "media_embed": {}, "thumbnail_width": null, "author_flair_template_id": null, "is_original_content": false, "user_reports": [], "secure_media": null, "is_reddit_media_domain": false, "is_meta": false, "category": null, "secure_media_embed": {}, "link_flair_text": "Discussion", "can_mod_post": false, "score": 103, "approved_by": null, "is_created_from_ads_ui": false, "author_premium": false, "thumbnail": "self", "edited": false, "author_flair_css_class": null, "author_flair_richtext": [], "gildings": {}, "content_categories": null, "is_self": true, "mod_note": null, "created": 1782859080.0, "link_flair_type": "richtext", "wls": 6, "removed_by_category": null, "banned_by": null, "author_flair_type": "text", "domain": "self.Python", "allow_live_comments": false, "selftext_html": "I saw one yesterday during an interview and it really confused me at first since the feature has been deprecated for so long.
\n\n
Are there still code bases out there running Python 2? I used Python 3.8 at my last job and that made me feel like a dinosaur.
\n
", "likes": null, "suggested_sort": null, "banned_at_utc": null, "view_count": null, "archived": false, "no_follow": false, "is_crosspostable": false, "pinned": false, "over_18": false, "all_awardings": [], "awarders": [], "media_only": false, "link_flair_template_id": "0df42996-1c5e-11ea-b1a0-0e44e1c5b731", "can_gild": false, "spoiler": false, "locked": false, "author_flair_text": null, "treatment_tags": [], "visited": false, "removed_by": null, "num_reports": null, "distinguished": null, "subreddit_id": "t5_2qh0y", "author_is_blocked": false, "mod_reason_by": null, "removal_reason": null, "link_flair_background_color": "#f50057", "id": "1uk3ym6", "is_robot_indexable": true, "report_reasons": null, "author": "GongtingLover", "discussion_type": null, "num_comments": 86, "send_replies": true, "contest_mode": false, "mod_reports": [], "author_patreon_flair": false, "author_flair_text_color": null, "permalink": "/r/Python/comments/1uk3ym6/whens_the_last_time_you_saw_python_2_super_syntax/", "stickied": false, "url": "https://www.reddit.com/r/Python/comments/1uk3ym6/whens_the_last_time_you_saw_python_2_super_syntax/", "subreddit_subscribers": 1493425, "created_utc": 1782859080.0, "num_crossposts": 0, "media": null, "is_video": false}}, {"kind": "t3", "data": {"approved_at_utc": null, "subreddit": "Python", "selftext": "The\u00a0Triple Product Property *(*TPP) algorithm is an obscure matmul algorithm that uses group theory (instead of linear algebra) to find matrix products.\n\nOne may summarize it as a fast fourier transform for multiplying matrices. The algorithm was published by Microsoft and Caltech researchers in 2003 but the original paper's math-heavy. I coded the paper in Python to make matrix multiplication research accessible to everyone.\n\nGitHub: [https://github.com/MurageKibicho/The-Annotated-Triple-Product-Property-Matrix-Multiplication-Algorithm/tree/main](https://github.com/MurageKibicho/The-Annotated-Triple-Product-Property-Matrix-Multiplication-Algorithm/tree/main)\n\nWritten Guide: [https://leetarxiv.substack.com/p/triple-product-property-matrix-multiplication](https://leetarxiv.substack.com/p/triple-product-property-matrix-multiplication)\n\n", "author_fullname": "t2_3xvmpjwh9", "saved": false, "mod_reason_title": null, "gilded": 0, "clicked": false, "title": "Annotated Triple Product Property Matrix Multiplication Algorithm In Python", "link_flair_richtext": [{"e": "text", "t": "Tutorial"}], "subreddit_name_prefixed": "r/Python", "hidden": false, "pwls": 6, "link_flair_css_class": "tutorial", "downs": 0, "thumbnail_height": null, "top_awarded_type": null, "hide_score": false, "name": "t3_1uknaq3", "quarantine": false, "link_flair_text_color": "dark", "upvote_ratio": 0.67, "author_flair_background_color": null, "subreddit_type": "public", "ups": 1, "total_awards_received": 0, "media_embed": {}, "thumbnail_width": null, "author_flair_template_id": null, "is_original_content": false, "user_reports": [], "secure_media": null, "is_reddit_media_domain": false, "is_meta": false, "category": null, "secure_media_embed": {}, "link_flair_text": "Tutorial", "can_mod_post": false, "score": 1, "approved_by": null, "is_created_from_ads_ui": false, "author_premium": false, "thumbnail": "self", "edited": false, "author_flair_css_class": null, "author_flair_richtext": [], "gildings": {}, "content_categories": null, "is_self": true, "mod_note": null, "created": 1782916193.0, "link_flair_type": "richtext", "wls": 6, "removed_by_category": null, "banned_by": null, "author_flair_type": "text", "domain": "self.Python", "allow_live_comments": false, "selftext_html": "", "likes": null, "suggested_sort": null, "banned_at_utc": null, "view_count": null, "archived": false, "no_follow": true, "is_crosspostable": false, "pinned": false, "over_18": false, "all_awardings": [], "awarders": [], "media_only": false, "link_flair_template_id": "7987a74c-04d8-11eb-84ca-0e0ac8b5a78f", "can_gild": false, "spoiler": false, "locked": false, "author_flair_text": null, "treatment_tags": [], "visited": false, "removed_by": null, "num_reports": null, "distinguished": null, "subreddit_id": "t5_2qh0y", "author_is_blocked": false, "mod_reason_by": null, "removal_reason": null, "link_flair_background_color": "#dadada", "id": "1uknaq3", "is_robot_indexable": true, "report_reasons": null, "author": "DataBaeBee", "discussion_type": null, "num_comments": 0, "send_replies": true, "contest_mode": false, "mod_reports": [], "author_patreon_flair": false, "author_flair_text_color": null, "permalink": "/r/Python/comments/1uknaq3/annotated_triple_product_property_matrix/", "stickied": false, "url": "https://www.reddit.com/r/Python/comments/1uknaq3/annotated_triple_product_property_matrix/", "subreddit_subscribers": 1493425, "created_utc": 1782916193.0, "num_crossposts": 0, "media": null, "is_video": false}}, {"kind": "t3", "data": {"approved_at_utc": null, "subreddit": "Python", "selftext": "I've been experimenting with AI agents and autocomplete platforms for a greenfield FastAPI project. In the first few weeks, it felt incredibly fast. But now that we've scaled to multiple routers, complex Pydantic schemas, and SQLAlchemy models, the structural debt is piling up.\n\nThe AI writes code that functions, but it constantly violates our architecture. It'll put complex business logic inside a route handler instead of the service layer, or it'll mess up async database sessions across modules. I find myself spending more time refactoring the structure of what it built than it would have taken to write the logic myself.\n\nIs anyone else hitting this scaling wall where AI utility drops off as codebase complexity grows? How are you keeping your system architecture clean?", "author_fullname": "t2_4xeh5jtc", "saved": false, "mod_reason_title": null, "gilded": 0, "clicked": false, "title": "Mitigating \"architectural drift\" in large Python backend codebases using AI tools", "link_flair_richtext": [{"e": "text", "t": "Discussion"}], "subreddit_name_prefixed": "r/Python", "hidden": false, "pwls": 6, "link_flair_css_class": "discussion", "downs": 0, "thumbnail_height": null, "top_awarded_type": null, "hide_score": false, "name": "t3_1ujy1a2", "quarantine": false, "link_flair_text_color": "light", "upvote_ratio": 0.73, "author_flair_background_color": null, "subreddit_type": "public", "ups": 32, "total_awards_received": 0, "media_embed": {}, "thumbnail_width": null, "author_flair_template_id": null, "is_original_content": false, "user_reports": [], "secure_media": null, "is_reddit_media_domain": false, "is_meta": false, "category": null, "secure_media_embed": {}, "link_flair_text": "Discussion", "can_mod_post": false, "score": 32, "approved_by": null, "is_created_from_ads_ui": false, "author_premium": false, "thumbnail": "self", "edited": false, "author_flair_css_class": null, "author_flair_richtext": [], "gildings": {}, "content_categories": null, "is_self": true, "mod_note": null, "created": 1782845636.0, "link_flair_type": "richtext", "wls": 6, "removed_by_category": null, "banned_by": null, "author_flair_type": "text", "domain": "self.Python", "allow_live_comments": false, "selftext_html": "I've been experimenting with AI agents and autocomplete platforms for a greenfield FastAPI project. In the first few weeks, it felt incredibly fast. But now that we've scaled to multiple routers, complex Pydantic schemas, and SQLAlchemy models, the structural debt is piling up.
\n\n
The AI writes code that functions, but it constantly violates our architecture. It'll put complex business logic inside a route handler instead of the service layer, or it'll mess up async database sessions across modules. I find myself spending more time refactoring the structure of what it built than it would have taken to write the logic myself.
\n\n
Is anyone else hitting this scaling wall where AI utility drops off as codebase complexity grows? How are you keeping your system architecture clean?
\n
", "likes": null, "suggested_sort": null, "banned_at_utc": null, "view_count": null, "archived": false, "no_follow": false, "is_crosspostable": false, "pinned": false, "over_18": false, "all_awardings": [], "awarders": [], "media_only": false, "link_flair_template_id": "0df42996-1c5e-11ea-b1a0-0e44e1c5b731", "can_gild": false, "spoiler": false, "locked": false, "author_flair_text": null, "treatment_tags": [], "visited": false, "removed_by": null, "num_reports": null, "distinguished": null, "subreddit_id": "t5_2qh0y", "author_is_blocked": false, "mod_reason_by": null, "removal_reason": null, "link_flair_background_color": "#f50057", "id": "1ujy1a2", "is_robot_indexable": true, "report_reasons": null, "author": "CrazyGeek7", "discussion_type": null, "num_comments": 42, "send_replies": true, "contest_mode": false, "mod_reports": [], "author_patreon_flair": false, "author_flair_text_color": null, "permalink": "/r/Python/comments/1ujy1a2/mitigating_architectural_drift_in_large_python/", "stickied": false, "url": "https://www.reddit.com/r/Python/comments/1ujy1a2/mitigating_architectural_drift_in_large_python/", "subreddit_subscribers": 1493425, "created_utc": 1782845636.0, "num_crossposts": 0, "media": null, "is_video": false}}, {"kind": "t3", "data": {"approved_at_utc": null, "subreddit": "Python", "selftext": "Please read this and contribute your opinions so that this becomes basic foundation for spring devs who adapt to python .\n\nhttps://bunny-learner.github.io/Python-Handbook-for-Spring-Devs/", "author_fullname": "t2_1gpwvz9l5s", "saved": false, "mod_reason_title": null, "gilded": 0, "clicked": false, "title": "Python handbook for spring devs", "link_flair_richtext": [{"e": "text", "t": "Resource"}], "subreddit_name_prefixed": "r/Python", "hidden": false, "pwls": 6, "link_flair_css_class": "resource", "downs": 0, "thumbnail_height": null, "top_awarded_type": null, "hide_score": false, "name": "t3_1ukn0wi", "quarantine": false, "link_flair_text_color": "light", "upvote_ratio": 0.25, "author_flair_background_color": null, "subreddit_type": "public", "ups": 0, "total_awards_received": 0, "media_embed": {}, "thumbnail_width": null, "author_flair_template_id": null, "is_original_content": false, "user_reports": [], "secure_media": null, "is_reddit_media_domain": false, "is_meta": false, "category": null, "secure_media_embed": {}, "link_flair_text": "Resource", "can_mod_post": false, "score": 0, "approved_by": null, "is_created_from_ads_ui": false, "author_premium": false, "thumbnail": "self", "edited": false, "author_flair_css_class": null, "author_flair_richtext": [], "gildings": {}, "content_categories": null, "is_self": true, "mod_note": null, "created": 1782915570.0, "link_flair_type": "richtext", "wls": 6, "removed_by_category": null, "banned_by": null, "author_flair_type": "text", "domain": "self.Python", "allow_live_comments": false, "selftext_html": "", "likes": null, "suggested_sort": null, "banned_at_utc": null, "view_count": null, "archived": false, "no_follow": true, "is_crosspostable": false, "pinned": false, "over_18": false, "all_awardings": [], "awarders": [], "media_only": false, "link_flair_template_id": "f9716fb2-4113-11ea-a3f1-0ef51f60f757", "can_gild": false, "spoiler": false, "locked": false, "author_flair_text": null, "treatment_tags": [], "visited": false, "removed_by": null, "num_reports": null, "distinguished": null, "subreddit_id": "t5_2qh0y", "author_is_blocked": false, "mod_reason_by": null, "removal_reason": null, "link_flair_background_color": "#ddbd37", "id": "1ukn0wi", "is_robot_indexable": true, "report_reasons": null, "author": "External-Wait-2583", "discussion_type": null, "num_comments": 2, "send_replies": true, "contest_mode": false, "mod_reports": [], "author_patreon_flair": false, "author_flair_text_color": null, "permalink": "/r/Python/comments/1ukn0wi/python_handbook_for_spring_devs/", "stickied": false, "url": "https://www.reddit.com/r/Python/comments/1ukn0wi/python_handbook_for_spring_devs/", "subreddit_subscribers": 1493425, "created_utc": 1782915570.0, "num_crossposts": 0, "media": null, "is_video": false}}, {"kind": "t3", "data": {"approved_at_utc": null, "subreddit": "Python", "selftext": "I just spent three hours trying to get a basic python cron script to send out a weekly web scraping summary. used to just use `smtplib` and a random gmail app password but google basically killed that workflow \n \nTried installing the official python sdk for one of the big email providers and it pulled in like 6 different async dependencies just to send a plain text string. It is genuinely insane how bloated the modern python ecosystem has gotten for the most basic tasks \n \nI ended up just writing a simple `requests.post()` webhook over to yaplet to handle the actual subscriber list and formatting because I absolutely refuse to fight with another bloated `__init__.py` or dns auth protocol this month \n \nsometimes it really feels like we spend 10% of our time writing actual python logic and 90% fighting with enterprise api wrappers tbh", "author_fullname": "t2_81nfn6e5d", "saved": false, "mod_reason_title": null, "gilded": 0, "clicked": false, "title": "Why is sending an automated email with python still a nightmare in 2026", "link_flair_richtext": [{"e": "text", "t": "Discussion"}], "subreddit_name_prefixed": "r/Python", "hidden": false, "pwls": 6, "link_flair_css_class": "discussion", "downs": 0, "thumbnail_height": null, "top_awarded_type": null, "hide_score": false, "name": "t3_1ukljb6", "quarantine": false, "link_flair_text_color": "light", "upvote_ratio": 0.25, "author_flair_background_color": null, "subreddit_type": "public", "ups": 0, "total_awards_received": 0, "media_embed": {}, "thumbnail_width": null, "author_flair_template_id": null, "is_original_content": false, "user_reports": [], "secure_media": null, "is_reddit_media_domain": false, "is_meta": false, "category": null, "secure_media_embed": {}, "link_flair_text": "Discussion", "can_mod_post": false, "score": 0, "approved_by": null, "is_created_from_ads_ui": false, "author_premium": false, "thumbnail": "self", "edited": false, "author_flair_css_class": null, "author_flair_richtext": [], "gildings": {}, "content_categories": null, "is_self": true, "mod_note": null, "created": 1782912026.0, "link_flair_type": "richtext", "wls": 6, "removed_by_category": null, "banned_by": null, "author_flair_type": "text", "domain": "self.Python", "allow_live_comments": false, "selftext_html": "I just spent three hours trying to get a basic python cron script to send out a weekly web scraping summary. used to just use smtplib and a random gmail app password but google basically killed that workflow
\n\n
Tried installing the official python sdk for one of the big email providers and it pulled in like 6 different async dependencies just to send a plain text string. It is genuinely insane how bloated the modern python ecosystem has gotten for the most basic tasks
\n\n
I ended up just writing a simple requests.post() webhook over to yaplet to handle the actual subscriber list and formatting because I absolutely refuse to fight with another bloated __init__.py or dns auth protocol this month
\n\n
sometimes it really feels like we spend 10% of our time writing actual python logic and 90% fighting with enterprise api wrappers tbh
\n
", "likes": null, "suggested_sort": null, "banned_at_utc": null, "view_count": null, "archived": false, "no_follow": true, "is_crosspostable": false, "pinned": false, "over_18": false, "all_awardings": [], "awarders": [], "media_only": false, "link_flair_template_id": "0df42996-1c5e-11ea-b1a0-0e44e1c5b731", "can_gild": false, "spoiler": false, "locked": false, "author_flair_text": null, "treatment_tags": [], "visited": false, "removed_by": null, "num_reports": null, "distinguished": null, "subreddit_id": "t5_2qh0y", "author_is_blocked": false, "mod_reason_by": null, "removal_reason": null, "link_flair_background_color": "#f50057", "id": "1ukljb6", "is_robot_indexable": true, "report_reasons": null, "author": "Crystallover1991", "discussion_type": null, "num_comments": 20, "send_replies": true, "contest_mode": false, "mod_reports": [], "author_patreon_flair": false, "author_flair_text_color": null, "permalink": "/r/Python/comments/1ukljb6/why_is_sending_an_automated_email_with_python/", "stickied": false, "url": "https://www.reddit.com/r/Python/comments/1ukljb6/why_is_sending_an_automated_email_with_python/", "subreddit_subscribers": 1493425, "created_utc": 1782912026.0, "num_crossposts": 0, "media": null, "is_video": false}}, {"kind": "t3", "data": {"approved_at_utc": null, "subreddit": "Python", "selftext": "This is the first part of a multi-part series exploring why `async/await` might not be the best concurrency pattern for most use cases, and what alternative models you should consider instead. Using Python for our practical examples, this opening post digs into the roots of `async/await`, guiding you through building a custom event loop from scratch using generators.\n\n[https://theblog.info/posts/asyncawait-is-a-plague-part-1-roots](https://theblog.info/posts/asyncawait-is-a-plague-part-1-roots)\n\n\n**Note:** This is Part 1 of a multi-part series. Instead of diving straight into why `async/await` can be problematic, this post explores the original motivations behind the pattern. Understanding how it works under the hood will provide the essential context for the issues we'll discuss in upcoming parts.", "author_fullname": "t2_rkfihkkzk", "saved": false, "mod_reason_title": null, "gilded": 0, "clicked": false, "title": "Async/Await is a Plague: Part 1 Roots", "link_flair_richtext": [{"e": "text", "t": "Discussion"}], "subreddit_name_prefixed": "r/Python", "hidden": false, "pwls": 6, "link_flair_css_class": "discussion", "downs": 0, "thumbnail_height": null, "top_awarded_type": null, "hide_score": false, "name": "t3_1uisy46", "quarantine": false, "link_flair_text_color": "light", "upvote_ratio": 0.7, "author_flair_background_color": null, "subreddit_type": "public", "ups": 73, "total_awards_received": 0, "media_embed": {}, "thumbnail_width": null, "author_flair_template_id": null, "is_original_content": false, "user_reports": [], "secure_media": null, "is_reddit_media_domain": false, "is_meta": false, "category": null, "secure_media_embed": {}, "link_flair_text": "Discussion", "can_mod_post": false, "score": 73, "approved_by": null, "is_created_from_ads_ui": false, "author_premium": false, "thumbnail": "self", "edited": 1782753438.0, "author_flair_css_class": null, "author_flair_richtext": [], "gildings": {}, "post_hint": "self", "content_categories": null, "is_self": true, "mod_note": null, "created": 1782740712.0, "link_flair_type": "richtext", "wls": 6, "removed_by_category": null, "banned_by": null, "author_flair_type": "text", "domain": "self.Python", "allow_live_comments": false, "selftext_html": "This is the first part of a multi-part series exploring why async/await might not be the best concurrency pattern for most use cases, and what alternative models you should consider instead. Using Python for our practical examples, this opening post digs into the roots of async/await, guiding you through building a custom event loop from scratch using generators.
\n\n
https://theblog.info/posts/asyncawait-is-a-plague-part-1-roots
\n\n
Note: This is Part 1 of a multi-part series. Instead of diving straight into why async/await can be problematic, this post explores the original motivations behind the pattern. Understanding how it works under the hood will provide the essential context for the issues we'll discuss in upcoming parts.
\n
", "likes": null, "suggested_sort": null, "banned_at_utc": null, "view_count": null, "archived": false, "no_follow": false, "is_crosspostable": false, "pinned": false, "over_18": false, "preview": {"images": [{"source": {"url": "https://external-preview.redd.it/o5iToZglarhA_St0cCPapqc_aoL8yr3wvMq-nTIXbBY.jpeg?auto=webp&s=8c085a9706bd5c46bf2669a92aec2fe9a968b931", "width": 640, "height": 640}, "resolutions": [{"url": "https://external-preview.redd.it/o5iToZglarhA_St0cCPapqc_aoL8yr3wvMq-nTIXbBY.jpeg?width=108&crop=smart&auto=webp&s=2ee3e5583e9679af89b4127ff8ef801ad96d7c21", "width": 108, "height": 108}, {"url": "https://external-preview.redd.it/o5iToZglarhA_St0cCPapqc_aoL8yr3wvMq-nTIXbBY.jpeg?width=216&crop=smart&auto=webp&s=6855cb906f7b5e61cd39e971a6813b92089c9ddc", "width": 216, "height": 216}, {"url": "https://external-preview.redd.it/o5iToZglarhA_St0cCPapqc_aoL8yr3wvMq-nTIXbBY.jpeg?width=320&crop=smart&auto=webp&s=6cc8885184c29b6a2bf5b3cda04f8e48f141681b", "width": 320, "height": 320}, {"url": "https://external-preview.redd.it/o5iToZglarhA_St0cCPapqc_aoL8yr3wvMq-nTIXbBY.jpeg?width=640&crop=smart&auto=webp&s=ed1a0969eb982fc4f33d3b725973b3d4a9165394", "width": 640, "height": 640}], "variants": {}, "id": "o5iToZglarhA_St0cCPapqc_aoL8yr3wvMq-nTIXbBY"}], "enabled": false}, "all_awardings": [], "awarders": [], "media_only": false, "link_flair_template_id": "0df42996-1c5e-11ea-b1a0-0e44e1c5b731", "can_gild": false, "spoiler": false, "locked": false, "author_flair_text": null, "treatment_tags": [], "visited": false, "removed_by": null, "num_reports": null, "distinguished": null, "subreddit_id": "t5_2qh0y", "author_is_blocked": false, "mod_reason_by": null, "removal_reason": null, "link_flair_background_color": "#f50057", "id": "1uisy46", "is_robot_indexable": true, "report_reasons": null, "author": "EntryNo8040", "discussion_type": null, "num_comments": 71, "send_replies": true, "contest_mode": false, "mod_reports": [], "author_patreon_flair": false, "author_flair_text_color": null, "permalink": "/r/Python/comments/1uisy46/asyncawait_is_a_plague_part_1_roots/", "stickied": false, "url": "https://www.reddit.com/r/Python/comments/1uisy46/asyncawait_is_a_plague_part_1_roots/", "subreddit_subscribers": 1493425, "created_utc": 1782740712.0, "num_crossposts": 0, "media": null, "is_video": false}}, {"kind": "t3", "data": {"approved_at_utc": null, "subreddit": "Python", "selftext": "# Weekly Wednesday Thread: Advanced Questions \ud83d\udc0d\n\nDive deep into Python with our Advanced Questions thread! This space is reserved for questions about more advanced Python topics, frameworks, and best practices.\n\n## How it Works:\n\n1. **Ask Away**: Post your advanced Python questions here.\n2. **Expert Insights**: Get answers from experienced developers.\n3. **Resource Pool**: Share or discover tutorials, articles, and tips.\n\n## Guidelines:\n\n* This thread is for **advanced questions only**. Beginner questions are welcome in our [Daily Beginner Thread](#daily-beginner-thread-link) every Thursday.\n* Questions that are not advanced may be removed and redirected to the appropriate thread.\n\n## Recommended Resources:\n\n* If you don't receive a response, consider exploring r/LearnPython or join the [Python Discord Server](https://discord.gg/python) for quicker assistance.\n\n## Example Questions:\n\n1. **How can you implement a custom memory allocator in Python?**\n2. **What are the best practices for optimizing Cython code for heavy numerical computations?**\n3. **How do you set up a multi-threaded architecture using Python's Global Interpreter Lock (GIL)?**\n4. **Can you explain the intricacies of metaclasses and how they influence object-oriented design in Python?**\n5. **How would you go about implementing a distributed task queue using Celery and RabbitMQ?**\n6. **What are some advanced use-cases for Python's decorators?**\n7. **How can you achieve real-time data streaming in Python with WebSockets?**\n8. **What are the performance implications of using native Python data structures vs NumPy arrays for large-scale data?**\n9. **Best practices for securing a Flask (or similar) REST API with OAuth 2.0?**\n10. **What are the best practices for using Python in a microservices architecture? (..and more generally, should I even use microservices?)**\n\nLet's deepen our Python knowledge together. Happy coding! \ud83c\udf1f", "author_fullname": "t2_6l4z3", "saved": false, "mod_reason_title": null, "gilded": 0, "clicked": false, "title": "Tuesday Daily Thread: Advanced questions", "link_flair_richtext": [{"a": ":pythonLogo:", "e": "emoji", "u": "https://emoji.redditmedia.com/8yxdpg6xxnr71_t5_2qh0y/pythonLogo"}, {"e": "text", "t": " Daily Thread"}], "subreddit_name_prefixed": "r/Python", "hidden": false, "pwls": 6, "link_flair_css_class": "daily-thread", "downs": 0, "thumbnail_height": null, "top_awarded_type": null, "hide_score": false, "name": "t3_1uj99ws", "quarantine": false, "link_flair_text_color": "light", "upvote_ratio": 0.67, "author_flair_background_color": null, "subreddit_type": "public", "ups": 3, "total_awards_received": 0, "media_embed": {}, "thumbnail_width": null, "author_flair_template_id": null, "is_original_content": false, "user_reports": [], "secure_media": null, "is_reddit_media_domain": false, "is_meta": false, "category": null, "secure_media_embed": {}, "link_flair_text": ":pythonLogo: Daily Thread", "can_mod_post": false, "score": 3, "approved_by": null, "is_created_from_ads_ui": false, "author_premium": true, "thumbnail": "self", "edited": false, "author_flair_css_class": null, "author_flair_richtext": [], "gildings": {}, "post_hint": "self", "content_categories": null, "is_self": true, "mod_note": null, "created": 1782777606.0, "link_flair_type": "richtext", "wls": 6, "removed_by_category": null, "banned_by": null, "author_flair_type": "text", "domain": "self.Python", "allow_live_comments": false, "selftext_html": "Weekly Wednesday Thread: Advanced Questions \ud83d\udc0d
\n\n
Dive deep into Python with our Advanced Questions thread! This space is reserved for questions about more advanced Python topics, frameworks, and best practices.
\n\n
How it Works:
\n\n
\n- Ask Away: Post your advanced Python questions here.
\n- Expert Insights: Get answers from experienced developers.
\n- Resource Pool: Share or discover tutorials, articles, and tips.
\n
\n\n
Guidelines:
\n\n
\n- This thread is for advanced questions only. Beginner questions are welcome in our Daily Beginner Thread every Thursday.
\n- Questions that are not advanced may be removed and redirected to the appropriate thread.
\n
\n\n
Recommended Resources:
\n\n
\n\n
Example Questions:
\n\n
\n- How can you implement a custom memory allocator in Python?
\n- What are the best practices for optimizing Cython code for heavy numerical computations?
\n- How do you set up a multi-threaded architecture using Python's Global Interpreter Lock (GIL)?
\n- Can you explain the intricacies of metaclasses and how they influence object-oriented design in Python?
\n- How would you go about implementing a distributed task queue using Celery and RabbitMQ?
\n- What are some advanced use-cases for Python's decorators?
\n- How can you achieve real-time data streaming in Python with WebSockets?
\n- What are the performance implications of using native Python data structures vs NumPy arrays for large-scale data?
\n- Best practices for securing a Flask (or similar) REST API with OAuth 2.0?
\n- What are the best practices for using Python in a microservices architecture? (..and more generally, should I even use microservices?)
\n
\n\n
Let's deepen our Python knowledge together. Happy coding! \ud83c\udf1f
\n
", "likes": null, "suggested_sort": null, "banned_at_utc": null, "view_count": null, "archived": false, "no_follow": false, "is_crosspostable": false, "pinned": false, "over_18": false, "preview": {"images": [{"source": {"url": "https://external-preview.redd.it/Qr0qqr0jX1TjZaLE6_zaVcWJHZQGJPofEJEedmb9MtI.jpeg?auto=webp&s=f0e96c458bf454a41999b79e0f2b4170f1e1c85f", "width": 512, "height": 288}, "resolutions": [{"url": "https://external-preview.redd.it/Qr0qqr0jX1TjZaLE6_zaVcWJHZQGJPofEJEedmb9MtI.jpeg?width=108&crop=smart&auto=webp&s=7726f1bd96bb293ee00f58330b9db8277d3a4e97", "width": 108, "height": 60}, {"url": "https://external-preview.redd.it/Qr0qqr0jX1TjZaLE6_zaVcWJHZQGJPofEJEedmb9MtI.jpeg?width=216&crop=smart&auto=webp&s=7592cc25c340779fdbd514118a98258c5def8dce", "width": 216, "height": 121}, {"url": "https://external-preview.redd.it/Qr0qqr0jX1TjZaLE6_zaVcWJHZQGJPofEJEedmb9MtI.jpeg?width=320&crop=smart&auto=webp&s=6dca793160bdafbbdac9126b927e2b64871738a5", "width": 320, "height": 180}], "variants": {}, "id": "Qr0qqr0jX1TjZaLE6_zaVcWJHZQGJPofEJEedmb9MtI"}], "enabled": false}, "all_awardings": [], "awarders": [], "media_only": false, "link_flair_template_id": "6c024934-de3f-11ea-a05a-0ea86b2be9a1", "can_gild": false, "spoiler": false, "locked": false, "author_flair_text": null, "treatment_tags": [], "visited": false, "removed_by": null, "num_reports": null, "distinguished": "moderator", "subreddit_id": "t5_2qh0y", "author_is_blocked": false, "mod_reason_by": null, "removal_reason": null, "link_flair_background_color": "#00a6a5", "id": "1uj99ws", "is_robot_indexable": true, "report_reasons": null, "author": "AutoModerator", "discussion_type": null, "num_comments": 4, "send_replies": false, "contest_mode": false, "mod_reports": [], "author_patreon_flair": false, "author_flair_text_color": null, "permalink": "/r/Python/comments/1uj99ws/tuesday_daily_thread_advanced_questions/", "stickied": false, "url": "https://www.reddit.com/r/Python/comments/1uj99ws/tuesday_daily_thread_advanced_questions/", "subreddit_subscribers": 1493425, "created_utc": 1782777606.0, "num_crossposts": 0, "media": null, "is_video": false}}, {"kind": "t3", "data": {"approved_at_utc": null, "subreddit": "Python", "selftext": "We compared the 3 pip-installable mesh boolean libraries on the task of pairwise mesh booleans at industry scale.\n\nFull write up: [https://polydera.com/algorithms/python-mesh-boolean-libraries-2026](https://polydera.com/algorithms/python-mesh-boolean-libraries-2026)\n\n#### Libraries tested\n\n- **[MeshLib](https://meshlib.io/) 3.1** \u2014 `pip install meshlib`. Simulation of Simplicity for degeneracy handling.\n- **[Manifold](https://github.com/elalish/manifold) 3.5** \u2014 `pip install manifold3d`. Deterministic floating point with symbolic perturbation.\n- **[trueform](https://polydera.com/trueform) 0.9.8** \u2014 `pip install trueform`. Topologically-exact arrangements via a bounded integer kernel. Ships native, python and WebAssembly.\n\nAll three are native cores (C++/Rust) with Python bindings.\n\n#### Protocol\n\nEach library is timed from input arrays (vertices, triangles) to output arrays of the same shape. Native-object construction \u2014 acceleration structures, trees, topology \u2014 plus the boolean, all in the timer. Only file I/O is outside. Best of 5, fresh objects every run; nothing amortised across calls.\n\n**Result agreement.** On every pair the three produced the same solid \u2014 signed volumes agree within floating-point tolerance. trueform and Manifold returned a closed, manifold mesh on all 1000 pairs; MeshLib on 999. The comparison is wall-clock only.\n\n**Corpus.** Random sets of solid, manifold, non-self-intersecting Thingi10K meshes, 200K to 1.5M polygons per operand. Each operand is normalised to unit extent, randomly rotated, and translated so the bounding boxes overlap; each pair takes the union. Thingi10K IDs and per-operand counts for every case are published: [pairwise corpus](https://github.com/polydera/trueform/blob/main/research/uncertainty-aware-mesh-csg/data/pairwise-corpus-ids.json).\n\n**Environment.** Apple M4 Max (arm64), macOS, CPython 3.13. Installed from PyPI: trueform 0.9.8, meshlib 3.1.0.75, manifold3d 3.5.1 \u2014 default builds, default thread count. On Apple Silicon the wheel's compiled architecture matters; all three ship native arm64 builds.\n\n#### Results\n\n**Of the libraries you can `pip install`, trueform was the fastest mesh boolean in Python** \u2014 fastest on every one of the 1000 pairwise pairs.\n\n**Pairwise** \u2014 one boolean per pair across the 1000-pair corpus.\n\n| library | median (ms) | geomean \u00d7 vs trueform | valid / 1000 |\n|---|---:|---:|---:|\n| trueform 0.9.8 | 18.0 | 1.0\u00d7 | 1000 |\n| MeshLib 3.1 | 87.6 | 4.9\u00d7 | 999 |\n| Manifold 3.5 | 120.3 | 6.9\u00d7 | 1000 |\n\n---\n\n*Disclosure: I'm one of the authors of trueform.*", "author_fullname": "t2_81ze3aps", "saved": false, "mod_reason_title": null, "gilded": 0, "clicked": false, "title": "Comparison and Benchmarks of Python Mesh Boolean Libraries at Industry Scale", "link_flair_richtext": [{"e": "text", "t": "Resource"}], "subreddit_name_prefixed": "r/Python", "hidden": false, "pwls": 6, "link_flair_css_class": "resource", "downs": 0, "thumbnail_height": null, "top_awarded_type": null, "hide_score": false, "name": "t3_1uins5r", "quarantine": false, "link_flair_text_color": "light", "upvote_ratio": 0.79, "author_flair_background_color": null, "subreddit_type": "public", "ups": 8, "total_awards_received": 0, "media_embed": {}, "thumbnail_width": null, "author_flair_template_id": null, "is_original_content": false, "user_reports": [], "secure_media": null, "is_reddit_media_domain": false, "is_meta": false, "category": null, "secure_media_embed": {}, "link_flair_text": "Resource", "can_mod_post": false, "score": 8, "approved_by": null, "is_created_from_ads_ui": false, "author_premium": false, "thumbnail": "self", "edited": 1782753231.0, "author_flair_css_class": null, "author_flair_richtext": [], "gildings": {}, "post_hint": "self", "content_categories": null, "is_self": true, "mod_note": null, "created": 1782725887.0, "link_flair_type": "richtext", "wls": 6, "removed_by_category": null, "banned_by": null, "author_flair_type": "text", "domain": "self.Python", "allow_live_comments": false, "selftext_html": "We compared the 3 pip-installable mesh boolean libraries on the task of pairwise mesh booleans at industry scale.
\n\n
Full write up: https://polydera.com/algorithms/python-mesh-boolean-libraries-2026
\n\n
Libraries tested
\n\n
\n- MeshLib 3.1 \u2014
pip install meshlib. Simulation of Simplicity for degeneracy handling. \n- Manifold 3.5 \u2014
pip install manifold3d. Deterministic floating point with symbolic perturbation. \n- trueform 0.9.8 \u2014
pip install trueform. Topologically-exact arrangements via a bounded integer kernel. Ships native, python and WebAssembly. \n
\n\n
All three are native cores (C++/Rust) with Python bindings.
\n\n
Protocol
\n\n
Each library is timed from input arrays (vertices, triangles) to output arrays of the same shape. Native-object construction \u2014 acceleration structures, trees, topology \u2014 plus the boolean, all in the timer. Only file I/O is outside. Best of 5, fresh objects every run; nothing amortised across calls.
\n\n
Result agreement. On every pair the three produced the same solid \u2014 signed volumes agree within floating-point tolerance. trueform and Manifold returned a closed, manifold mesh on all 1000 pairs; MeshLib on 999. The comparison is wall-clock only.
\n\n
Corpus. Random sets of solid, manifold, non-self-intersecting Thingi10K meshes, 200K to 1.5M polygons per operand. Each operand is normalised to unit extent, randomly rotated, and translated so the bounding boxes overlap; each pair takes the union. Thingi10K IDs and per-operand counts for every case are published: pairwise corpus.
\n\n
Environment. Apple M4 Max (arm64), macOS, CPython 3.13. Installed from PyPI: trueform 0.9.8, meshlib 3.1.0.75, manifold3d 3.5.1 \u2014 default builds, default thread count. On Apple Silicon the wheel's compiled architecture matters; all three ship native arm64 builds.
\n\n
Results
\n\n
Of the libraries you can pip install, trueform was the fastest mesh boolean in Python \u2014 fastest on every one of the 1000 pairwise pairs.
\n\n
Pairwise \u2014 one boolean per pair across the 1000-pair corpus.
\n\n
\n\n| library | \nmedian (ms) | \ngeomean \u00d7 vs trueform | \nvalid / 1000 | \n
\n\n\n| trueform 0.9.8 | \n18.0 | \n1.0\u00d7 | \n1000 | \n
\n\n| MeshLib 3.1 | \n87.6 | \n4.9\u00d7 | \n999 | \n
\n\n| Manifold 3.5 | \n120.3 | \n6.9\u00d7 | \n1000 | \n
\n
\n\n
\n\n
Disclosure: I'm one of the authors of trueform.
\n
", "likes": null, "suggested_sort": null, "banned_at_utc": null, "view_count": null, "archived": false, "no_follow": false, "is_crosspostable": false, "pinned": false, "over_18": false, "preview": {"images": [{"source": {"url": "https://external-preview.redd.it/uP9ziF1Ybs-odwNAz2IxyEjZSvHb6KCbsUD3bZsW7Rk.png?auto=webp&s=9872ff4503eed4216dbc3d09833ceb2ce9893e9d", "width": 1200, "height": 600}, "resolutions": [{"url": "https://external-preview.redd.it/uP9ziF1Ybs-odwNAz2IxyEjZSvHb6KCbsUD3bZsW7Rk.png?width=108&crop=smart&auto=webp&s=48a6c26427e9bcc0b3e033694a4ad7864ae8aec6", "width": 108, "height": 54}, {"url": "https://external-preview.redd.it/uP9ziF1Ybs-odwNAz2IxyEjZSvHb6KCbsUD3bZsW7Rk.png?width=216&crop=smart&auto=webp&s=3448012d2ca17920431ff0b9af75287cb7ddb127", "width": 216, "height": 108}, {"url": "https://external-preview.redd.it/uP9ziF1Ybs-odwNAz2IxyEjZSvHb6KCbsUD3bZsW7Rk.png?width=320&crop=smart&auto=webp&s=e44c7768721ffdd42c421ee7ded2390eeee2dcff", "width": 320, "height": 160}, {"url": "https://external-preview.redd.it/uP9ziF1Ybs-odwNAz2IxyEjZSvHb6KCbsUD3bZsW7Rk.png?width=640&crop=smart&auto=webp&s=bd31638b30f1d7b12f29c5eab21fed8a1aa66bb6", "width": 640, "height": 320}, {"url": "https://external-preview.redd.it/uP9ziF1Ybs-odwNAz2IxyEjZSvHb6KCbsUD3bZsW7Rk.png?width=960&crop=smart&auto=webp&s=ec326eb5a02b7424897a25e5ef64b39c6b20123b", "width": 960, "height": 480}, {"url": "https://external-preview.redd.it/uP9ziF1Ybs-odwNAz2IxyEjZSvHb6KCbsUD3bZsW7Rk.png?width=1080&crop=smart&auto=webp&s=bd5479c4f871219c0a41d93d1ba87ae6d8c6e9c2", "width": 1080, "height": 540}], "variants": {}, "id": "uP9ziF1Ybs-odwNAz2IxyEjZSvHb6KCbsUD3bZsW7Rk"}], "enabled": false}, "all_awardings": [], "awarders": [], "media_only": false, "link_flair_template_id": "f9716fb2-4113-11ea-a3f1-0ef51f60f757", "can_gild": false, "spoiler": false, "locked": false, "author_flair_text": null, "treatment_tags": [], "visited": false, "removed_by": null, "num_reports": null, "distinguished": null, "subreddit_id": "t5_2qh0y", "author_is_blocked": false, "mod_reason_by": null, "removal_reason": null, "link_flair_background_color": "#ddbd37", "id": "1uins5r", "is_robot_indexable": true, "report_reasons": null, "author": "Separate-Summer-6027", "discussion_type": null, "num_comments": 4, "send_replies": true, "contest_mode": false, "mod_reports": [], "author_patreon_flair": false, "author_flair_text_color": null, "permalink": "/r/Python/comments/1uins5r/comparison_and_benchmarks_of_python_mesh_boolean/", "stickied": false, "url": "https://www.reddit.com/r/Python/comments/1uins5r/comparison_and_benchmarks_of_python_mesh_boolean/", "subreddit_subscribers": 1493425, "created_utc": 1782725887.0, "num_crossposts": 0, "media": null, "is_video": false}}, {"kind": "t3", "data": {"approved_at_utc": null, "subreddit": "Python", "selftext": "# Weekly Thread: Project Ideas \ud83d\udca1\n\nWelcome to our weekly Project Ideas thread! Whether you're a newbie looking for a first project or an expert seeking a new challenge, this is the place for you.\n\n## How it Works:\n\n1. **Suggest a Project**: Comment your project idea\u2014be it beginner-friendly or advanced.\n2. **Build & Share**: If you complete a project, reply to the original comment, share your experience, and attach your source code.\n3. **Explore**: Looking for ideas? Check out Al Sweigart's [\"The Big Book of Small Python Projects\"](https://www.amazon.com/Big-Book-Small-Python-Programming/dp/1718501242) for inspiration.\n\n## Guidelines:\n\n* Clearly state the difficulty level.\n* Provide a brief description and, if possible, outline the tech stack.\n* Feel free to link to tutorials or resources that might help.\n\n# Example Submissions:\n\n## Project Idea: Chatbot\n\n**Difficulty**: Intermediate\n\n**Tech Stack**: Python, NLP, Flask/FastAPI/Litestar \n\n**Description**: Create a chatbot that can answer FAQs for a website.\n\n**Resources**: [Building a Chatbot with Python](https://www.youtube.com/watch?v=a37BL0stIuM)\n\n# Project Idea: Weather Dashboard\n\n**Difficulty**: Beginner\n\n**Tech Stack**: HTML, CSS, JavaScript, API\n\n**Description**: Build a dashboard that displays real-time weather information using a weather API.\n\n**Resources**: [Weather API Tutorial](https://www.youtube.com/watch?v=9P5MY_2i7K8)\n\n## Project Idea: File Organizer\n\n**Difficulty**: Beginner\n\n**Tech Stack**: Python, File I/O\n\n**Description**: Create a script that organizes files in a directory into sub-folders based on file type.\n\n**Resources**: [Automate the Boring Stuff: Organizing Files](https://automatetheboringstuff.com/2e/chapter9/)\n\nLet's help each other grow. Happy coding! \ud83c\udf1f", "author_fullname": "t2_6l4z3", "saved": false, "mod_reason_title": null, "gilded": 0, "clicked": false, "title": "Monday Daily Thread: Project ideas!", "link_flair_richtext": [{"a": ":pythonLogo:", "e": "emoji", "u": "https://emoji.redditmedia.com/8yxdpg6xxnr71_t5_2qh0y/pythonLogo"}, {"e": "text", "t": " Daily Thread"}], "subreddit_name_prefixed": "r/Python", "hidden": false, "pwls": 6, "link_flair_css_class": "daily-thread", "downs": 0, "thumbnail_height": null, "top_awarded_type": null, "hide_score": false, "name": "t3_1uictw2", "quarantine": false, "link_flair_text_color": "light", "upvote_ratio": 0.67, "author_flair_background_color": null, "subreddit_type": "public", "ups": 4, "total_awards_received": 0, "media_embed": {}, "thumbnail_width": null, "author_flair_template_id": null, "is_original_content": false, "user_reports": [], "secure_media": null, "is_reddit_media_domain": false, "is_meta": false, "category": null, "secure_media_embed": {}, "link_flair_text": ":pythonLogo: Daily Thread", "can_mod_post": false, "score": 4, "approved_by": null, "is_created_from_ads_ui": false, "author_premium": true, "thumbnail": "self", "edited": false, "author_flair_css_class": null, "author_flair_richtext": [], "gildings": {}, "post_hint": "self", "content_categories": null, "is_self": true, "mod_note": null, "created": 1782691206.0, "link_flair_type": "richtext", "wls": 6, "removed_by_category": null, "banned_by": null, "author_flair_type": "text", "domain": "self.Python", "allow_live_comments": false, "selftext_html": "Weekly Thread: Project Ideas \ud83d\udca1
\n\n
Welcome to our weekly Project Ideas thread! Whether you're a newbie looking for a first project or an expert seeking a new challenge, this is the place for you.
\n\n
How it Works:
\n\n
\n- Suggest a Project: Comment your project idea\u2014be it beginner-friendly or advanced.
\n- Build & Share: If you complete a project, reply to the original comment, share your experience, and attach your source code.
\n- Explore: Looking for ideas? Check out Al Sweigart's "The Big Book of Small Python Projects" for inspiration.
\n
\n\n
Guidelines:
\n\n
\n- Clearly state the difficulty level.
\n- Provide a brief description and, if possible, outline the tech stack.
\n- Feel free to link to tutorials or resources that might help.
\n
\n\n
Example Submissions:
\n\n
Project Idea: Chatbot
\n\n
Difficulty: Intermediate
\n\n
Tech Stack: Python, NLP, Flask/FastAPI/Litestar
\n\n
Description: Create a chatbot that can answer FAQs for a website.
\n\n
Resources: Building a Chatbot with Python
\n\n
Project Idea: Weather Dashboard
\n\n
Difficulty: Beginner
\n\n
Tech Stack: HTML, CSS, JavaScript, API
\n\n
Description: Build a dashboard that displays real-time weather information using a weather API.
\n\n
Resources: Weather API Tutorial
\n\n
Project Idea: File Organizer
\n\n
Difficulty: Beginner
\n\n
Tech Stack: Python, File I/O
\n\n
Description: Create a script that organizes files in a directory into sub-folders based on file type.
\n\n
Resources: Automate the Boring Stuff: Organizing Files
\n\n
Let's help each other grow. Happy coding! \ud83c\udf1f
\n
", "likes": null, "suggested_sort": null, "banned_at_utc": null, "view_count": null, "archived": false, "no_follow": false, "is_crosspostable": false, "pinned": false, "over_18": false, "preview": {"images": [{"source": {"url": "https://external-preview.redd.it/wyRlnnC4nIHWRfWMUIBnHvHMsP98N9mROJtKXbnwKWI.png?auto=webp&s=8cdb17f0919f23f3fc3c0bd9dac21cd40118adda", "width": 1910, "height": 1000}, "resolutions": [{"url": "https://external-preview.redd.it/wyRlnnC4nIHWRfWMUIBnHvHMsP98N9mROJtKXbnwKWI.png?width=108&crop=smart&auto=webp&s=c7ef9713fb4fbf51d0d7da30fb558f95324a395b", "width": 108, "height": 56}, {"url": "https://external-preview.redd.it/wyRlnnC4nIHWRfWMUIBnHvHMsP98N9mROJtKXbnwKWI.png?width=216&crop=smart&auto=webp&s=70f4ef0366eafa569960666b4537977954dc4da4", "width": 216, "height": 113}, {"url": "https://external-preview.redd.it/wyRlnnC4nIHWRfWMUIBnHvHMsP98N9mROJtKXbnwKWI.png?width=320&crop=smart&auto=webp&s=e88e6f574ea2b6abf3644be5140a1ed8ad6d613c", "width": 320, "height": 167}, {"url": "https://external-preview.redd.it/wyRlnnC4nIHWRfWMUIBnHvHMsP98N9mROJtKXbnwKWI.png?width=640&crop=smart&auto=webp&s=290ace7209dd3df0a237ec970a6a8b1662d523e1", "width": 640, "height": 335}, {"url": "https://external-preview.redd.it/wyRlnnC4nIHWRfWMUIBnHvHMsP98N9mROJtKXbnwKWI.png?width=960&crop=smart&auto=webp&s=421952297faebb04d1038184216c053ab1f0bb56", "width": 960, "height": 502}, {"url": "https://external-preview.redd.it/wyRlnnC4nIHWRfWMUIBnHvHMsP98N9mROJtKXbnwKWI.png?width=1080&crop=smart&auto=webp&s=2e3704dd3e397c6dbebe004c6cce33e8cd82d316", "width": 1080, "height": 565}], "variants": {}, "id": "wyRlnnC4nIHWRfWMUIBnHvHMsP98N9mROJtKXbnwKWI"}], "enabled": false}, "all_awardings": [], "awarders": [], "media_only": false, "link_flair_template_id": "6c024934-de3f-11ea-a05a-0ea86b2be9a1", "can_gild": false, "spoiler": false, "locked": false, "author_flair_text": null, "treatment_tags": [], "visited": false, "removed_by": null, "num_reports": null, "distinguished": "moderator", "subreddit_id": "t5_2qh0y", "author_is_blocked": false, "mod_reason_by": null, "removal_reason": null, "link_flair_background_color": "#00a6a5", "id": "1uictw2", "is_robot_indexable": true, "report_reasons": null, "author": "AutoModerator", "discussion_type": null, "num_comments": 0, "send_replies": false, "contest_mode": false, "mod_reports": [], "author_patreon_flair": false, "author_flair_text_color": null, "permalink": "/r/Python/comments/1uictw2/monday_daily_thread_project_ideas/", "stickied": false, "url": "https://www.reddit.com/r/Python/comments/1uictw2/monday_daily_thread_project_ideas/", "subreddit_subscribers": 1493425, "created_utc": 1782691206.0, "num_crossposts": 0, "media": null, "is_video": false}}, {"kind": "t3", "data": {"approved_at_utc": null, "subreddit": "Python", "selftext": "Hey r/learnpython \ud83d\udc4b\n\nBuilt PyRun (pyrun.in) \u2014 a browser-based Python learning platform \n\npowered by Pyodide. Write and run Python directly in your browser, \n\nzero setup needed.\n\nWhat's included:\n\n\u2022 Interactive Python editor (Monaco-based)\n\n\u2022 Structured lessons from beginner to advanced\n\n\u2022 Instant output \u2014 no backend, runs locally in your browser\n\n\u2022 Free to use\n\nWould love feedback from this community \u2014 what topics or features \n\nwould make this more useful for you?\n\nLink: https://pyrun.in", "author_fullname": "t2_2hinuthhdk", "saved": false, "mod_reason_title": null, "gilded": 0, "clicked": false, "title": "I built a free in-browser Python learning platform \u2013 no installs, just open and code", "link_flair_richtext": [{"e": "text", "t": "Tutorial"}], "subreddit_name_prefixed": "r/Python", "hidden": false, "pwls": 6, "link_flair_css_class": "tutorial", "downs": 0, "thumbnail_height": null, "top_awarded_type": null, "hide_score": false, "name": "t3_1uiw602", "quarantine": false, "link_flair_text_color": "dark", "upvote_ratio": 0.25, "author_flair_background_color": null, "subreddit_type": "public", "ups": 0, "total_awards_received": 0, "media_embed": {}, "thumbnail_width": null, "author_flair_template_id": null, "is_original_content": false, "user_reports": [], "secure_media": null, "is_reddit_media_domain": false, "is_meta": false, "category": null, "secure_media_embed": {}, "link_flair_text": "Tutorial", "can_mod_post": false, "score": 0, "approved_by": null, "is_created_from_ads_ui": false, "author_premium": false, "thumbnail": "self", "edited": false, "author_flair_css_class": null, "author_flair_richtext": [], "gildings": {}, "post_hint": "self", "content_categories": null, "is_self": true, "mod_note": null, "created": 1782747928.0, "link_flair_type": "richtext", "wls": 6, "removed_by_category": null, "banned_by": null, "author_flair_type": "text", "domain": "self.Python", "allow_live_comments": false, "selftext_html": "Hey r/learnpython \ud83d\udc4b
\n\n
Built PyRun (pyrun.in) \u2014 a browser-based Python learning platform
\n\n
powered by Pyodide. Write and run Python directly in your browser,
\n\n
zero setup needed.
\n\n
What's included:
\n\n
\u2022 Interactive Python editor (Monaco-based)
\n\n
\u2022 Structured lessons from beginner to advanced
\n\n
\u2022 Instant output \u2014 no backend, runs locally in your browser
\n\n
\u2022 Free to use
\n\n
Would love feedback from this community \u2014 what topics or features
\n\n
would make this more useful for you?
\n\n
Link: https://pyrun.in
\n
", "likes": null, "suggested_sort": null, "banned_at_utc": null, "view_count": null, "archived": false, "no_follow": true, "is_crosspostable": false, "pinned": false, "over_18": false, "preview": {"images": [{"source": {"url": "https://external-preview.redd.it/Zbc0eUv1jXytp6GEqwGvRsh-PTjb-xLlLDl976BYG_g.png?auto=webp&s=30a4651979e078369eee9b8f8707a356f8a1cc11", "width": 1200, "height": 630}, "resolutions": [{"url": "https://external-preview.redd.it/Zbc0eUv1jXytp6GEqwGvRsh-PTjb-xLlLDl976BYG_g.png?width=108&crop=smart&auto=webp&s=963a21f143c1243528c655e9506c1d7c98703ade", "width": 108, "height": 56}, {"url": "https://external-preview.redd.it/Zbc0eUv1jXytp6GEqwGvRsh-PTjb-xLlLDl976BYG_g.png?width=216&crop=smart&auto=webp&s=fb89b2dda88c5cf5963a2e6ae03251a188ae0826", "width": 216, "height": 113}, {"url": "https://external-preview.redd.it/Zbc0eUv1jXytp6GEqwGvRsh-PTjb-xLlLDl976BYG_g.png?width=320&crop=smart&auto=webp&s=e38c05daf7fe3afd90e786b07c97f0bff68f0f67", "width": 320, "height": 168}, {"url": "https://external-preview.redd.it/Zbc0eUv1jXytp6GEqwGvRsh-PTjb-xLlLDl976BYG_g.png?width=640&crop=smart&auto=webp&s=29b6d153f034b3b0117e66c68b8ae6a92f4ae98a", "width": 640, "height": 336}, {"url": "https://external-preview.redd.it/Zbc0eUv1jXytp6GEqwGvRsh-PTjb-xLlLDl976BYG_g.png?width=960&crop=smart&auto=webp&s=279a2855c24fae439dd2cc3a0d9b7011039fed27", "width": 960, "height": 504}, {"url": "https://external-preview.redd.it/Zbc0eUv1jXytp6GEqwGvRsh-PTjb-xLlLDl976BYG_g.png?width=1080&crop=smart&auto=webp&s=09560fe60b9e09b9e38403956c12f60d4437efc5", "width": 1080, "height": 567}], "variants": {}, "id": "Zbc0eUv1jXytp6GEqwGvRsh-PTjb-xLlLDl976BYG_g"}], "enabled": false}, "all_awardings": [], "awarders": [], "media_only": false, "link_flair_template_id": "7987a74c-04d8-11eb-84ca-0e0ac8b5a78f", "can_gild": false, "spoiler": false, "locked": false, "author_flair_text": null, "treatment_tags": [], "visited": false, "removed_by": null, "num_reports": null, "distinguished": null, "subreddit_id": "t5_2qh0y", "author_is_blocked": false, "mod_reason_by": null, "removal_reason": null, "link_flair_background_color": "#dadada", "id": "1uiw602", "is_robot_indexable": true, "report_reasons": null, "author": "No_Monitor3155", "discussion_type": null, "num_comments": 2, "send_replies": true, "contest_mode": false, "mod_reports": [], "author_patreon_flair": false, "author_flair_text_color": null, "permalink": "/r/Python/comments/1uiw602/i_built_a_free_inbrowser_python_learning_platform/", "stickied": false, "url": "https://www.reddit.com/r/Python/comments/1uiw602/i_built_a_free_inbrowser_python_learning_platform/", "subreddit_subscribers": 1493425, "created_utc": 1782747928.0, "num_crossposts": 0, "media": null, "is_video": false}}, {"kind": "t3", "data": {"approved_at_utc": null, "subreddit": "Python", "selftext": "I'm a coding beginner and after i updated windows the layout started looking different (i can't add pics), i want it to go back to what it used to be as I'm not sure how to use it. ", "author_fullname": "t2_7pzenp33", "saved": false, "mod_reason_title": null, "gilded": 0, "clicked": false, "title": "why is pycharm doing this after a windows update", "link_flair_richtext": [{"e": "text", "t": "Discussion"}], "subreddit_name_prefixed": "r/Python", "hidden": false, "pwls": 6, "link_flair_css_class": "discussion", "downs": 0, "thumbnail_height": null, "top_awarded_type": null, "hide_score": false, "name": "t3_1uj092r", "quarantine": false, "link_flair_text_color": "light", "upvote_ratio": 0.08, "author_flair_background_color": null, "subreddit_type": "public", "ups": 0, "total_awards_received": 0, "media_embed": {}, "thumbnail_width": null, "author_flair_template_id": null, "is_original_content": false, "user_reports": [], "secure_media": null, "is_reddit_media_domain": false, "is_meta": false, "category": null, "secure_media_embed": {}, "link_flair_text": "Discussion", "can_mod_post": false, "score": 0, "approved_by": null, "is_created_from_ads_ui": false, "author_premium": false, "thumbnail": "self", "edited": false, "author_flair_css_class": null, "author_flair_richtext": [], "gildings": {}, "content_categories": null, "is_self": true, "mod_note": null, "created": 1782756782.0, "link_flair_type": "richtext", "wls": 6, "removed_by_category": null, "banned_by": null, "author_flair_type": "text", "domain": "self.Python", "allow_live_comments": false, "selftext_html": "I'm a coding beginner and after i updated windows the layout started looking different (i can't add pics), i want it to go back to what it used to be as I'm not sure how to use it.
\n
", "likes": null, "suggested_sort": null, "banned_at_utc": null, "view_count": null, "archived": false, "no_follow": true, "is_crosspostable": false, "pinned": false, "over_18": false, "all_awardings": [], "awarders": [], "media_only": false, "link_flair_template_id": "0df42996-1c5e-11ea-b1a0-0e44e1c5b731", "can_gild": false, "spoiler": false, "locked": false, "author_flair_text": null, "treatment_tags": [], "visited": false, "removed_by": null, "num_reports": null, "distinguished": null, "subreddit_id": "t5_2qh0y", "author_is_blocked": false, "mod_reason_by": null, "removal_reason": null, "link_flair_background_color": "#f50057", "id": "1uj092r", "is_robot_indexable": true, "report_reasons": null, "author": "Regular_Philosophy_9", "discussion_type": null, "num_comments": 12, "send_replies": true, "contest_mode": false, "mod_reports": [], "author_patreon_flair": false, "author_flair_text_color": null, "permalink": "/r/Python/comments/1uj092r/why_is_pycharm_doing_this_after_a_windows_update/", "stickied": false, "url": "https://www.reddit.com/r/Python/comments/1uj092r/why_is_pycharm_doing_this_after_a_windows_update/", "subreddit_subscribers": 1493425, "created_utc": 1782756782.0, "num_crossposts": 0, "media": null, "is_video": false}}, {"kind": "t3", "data": {"approved_at_utc": null, "subreddit": "Python", "selftext": "Hey everyone and all space enthusiasts,\n\n \nOn April 13, 2029, the asteroid **99942 Apophis** will fly past Earth at roughly 38,000 km. Closer than our geostationary satellites! Its discovery history was pretty interesting, because in the beginning there was a 2.7 % chance of an impact (don't worry, it is almost null now). So I decided to use NASA/JPL's SPICE toolkit using Python (`spiceypy`) to calculate the encounter's properties.\n\n \nI documented the entire project in a Jupyter Notebook and put together a complete video walk-through tutorial. Code: [https://github.com/ThomasAlbin/Space-Science-With-Python/blob/main/2026/04\\_SPICE\\_Apohis\\_2029\\_Flyby.ipynb](https://github.com/ThomasAlbin/Space-Science-With-Python/blob/main/2026/04_SPICE_Apohis_2029_Flyby.ipynb)\n\nVideo: [https://www.youtube.com/watch?v=j4mJTR-BTto](https://www.youtube.com/watch?v=j4mJTR-BTto)\n\nWhat the tutorial does (and why it's 30 minutes long \ud83d\ude05):\n\n* Computing the time when Apophis enters Earth's gravitational vicinity (the Sphere of Influece)\n* Computing the closest appraoch (distance and time)\n* Computing how the orbital elements (the dynamical properties to describe orbits in space) change after the encounter with Earth.\n\nBy the way: I used also Python + NASA's Cosmographia to create a nice 3D animation of the encounter :). But I will post it soon on my YouTube channel. Since the corresponding code is a complete mess I won't post it here, because I will only post the animation. I have to clean it up...\n\n \nBest,\n\nThomas (your Cassini/Huygens scientist)", "author_fullname": "t2_67yyoriy", "saved": false, "mod_reason_title": null, "gilded": 0, "clicked": false, "title": "Computing the close encounter between Apophis and Earth in 2029 (tutorial)", "link_flair_richtext": [{"e": "text", "t": "Tutorial"}], "subreddit_name_prefixed": "r/Python", "hidden": false, "pwls": 6, "link_flair_css_class": "tutorial", "downs": 0, "thumbnail_height": null, "top_awarded_type": null, "hide_score": false, "name": "t3_1uhutaj", "quarantine": false, "link_flair_text_color": "dark", "upvote_ratio": 0.9, "author_flair_background_color": "#b8001f", "subreddit_type": "public", "ups": 23, "total_awards_received": 0, "media_embed": {}, "thumbnail_width": null, "author_flair_template_id": "01f57bbe-537c-11ee-bb0d-6ef63b2ae5b9", "is_original_content": false, "user_reports": [], "secure_media": null, "is_reddit_media_domain": false, "is_meta": false, "category": null, "secure_media_embed": {}, "link_flair_text": "Tutorial", "can_mod_post": false, "score": 23, "approved_by": null, "is_created_from_ads_ui": false, "author_premium": false, "thumbnail": "self", "edited": false, "author_flair_css_class": null, "author_flair_richtext": [{"e": "text", "t": "git push -f"}], "gildings": {}, "content_categories": null, "is_self": true, "mod_note": null, "created": 1782645910.0, "link_flair_type": "richtext", "wls": 6, "removed_by_category": null, "banned_by": null, "author_flair_type": "richtext", "domain": "self.Python", "allow_live_comments": false, "selftext_html": "Hey everyone and all space enthusiasts,
\n\n
On April 13, 2029, the asteroid 99942 Apophis will fly past Earth at roughly 38,000 km. Closer than our geostationary satellites! Its discovery history was pretty interesting, because in the beginning there was a 2.7 % chance of an impact (don't worry, it is almost null now). So I decided to use NASA/JPL's SPICE toolkit using Python (spiceypy) to calculate the encounter's properties.
\n\n
I documented the entire project in a Jupyter Notebook and put together a complete video walk-through tutorial. Code: https://github.com/ThomasAlbin/Space-Science-With-Python/blob/main/2026/04_SPICE_Apohis_2029_Flyby.ipynb
\n\n
Video: https://www.youtube.com/watch?v=j4mJTR-BTto
\n\n
What the tutorial does (and why it's 30 minutes long \ud83d\ude05):
\n\n
\n- Computing the time when Apophis enters Earth's gravitational vicinity (the Sphere of Influece)
\n- Computing the closest appraoch (distance and time)
\n- Computing how the orbital elements (the dynamical properties to describe orbits in space) change after the encounter with Earth.
\n
\n\n
By the way: I used also Python + NASA's Cosmographia to create a nice 3D animation of the encounter :). But I will post it soon on my YouTube channel. Since the corresponding code is a complete mess I won't post it here, because I will only post the animation. I have to clean it up...
\n\n
Best,
\n\n
Thomas (your Cassini/Huygens scientist)
\n
", "likes": null, "suggested_sort": null, "banned_at_utc": null, "view_count": null, "archived": false, "no_follow": false, "is_crosspostable": false, "pinned": false, "over_18": false, "all_awardings": [], "awarders": [], "media_only": false, "link_flair_template_id": "7987a74c-04d8-11eb-84ca-0e0ac8b5a78f", "can_gild": false, "spoiler": false, "locked": false, "author_flair_text": "git push -f", "treatment_tags": [], "visited": false, "removed_by": null, "num_reports": null, "distinguished": null, "subreddit_id": "t5_2qh0y", "author_is_blocked": false, "mod_reason_by": null, "removal_reason": null, "link_flair_background_color": "#dadada", "id": "1uhutaj", "is_robot_indexable": true, "report_reasons": null, "author": "MrAstroThomas", "discussion_type": null, "num_comments": 10, "send_replies": true, "contest_mode": false, "mod_reports": [], "author_patreon_flair": false, "author_flair_text_color": "light", "permalink": "/r/Python/comments/1uhutaj/computing_the_close_encounter_between_apophis_and/", "stickied": false, "url": "https://www.reddit.com/r/Python/comments/1uhutaj/computing_the_close_encounter_between_apophis_and/", "subreddit_subscribers": 1493425, "created_utc": 1782645910.0, "num_crossposts": 0, "media": null, "is_video": false}}, {"kind": "t3", "data": {"approved_at_utc": null, "subreddit": "Python", "selftext": "Hi guys this tutorial is about training a neural network in Python to sort lists of numbers using the Gumbel-Sinkhorn architecture from the original 2018 paper.\n\n\n\nGithub: [https://github.com/MurageKibicho/Neural-Sorting-Algorithms-Gumbel-Sinkhorn-Networks/tree/main](https://github.com/MurageKibicho/Neural-Sorting-Algorithms-Gumbel-Sinkhorn-Networks/tree/main)\n\n\n\nWriteup: [https://leetarxiv.substack.com/p/gumbel-sinkhorn-neural-sort](https://leetarxiv.substack.com/p/gumbel-sinkhorn-neural-sort)", "author_fullname": "t2_3xvmpjwh9", "saved": false, "mod_reason_title": null, "gilded": 0, "clicked": false, "title": "Neural Sorting Algorithms: Gumbel-Sinkhorn Networks", "link_flair_richtext": [{"e": "text", "t": "Tutorial"}], "subreddit_name_prefixed": "r/Python", "hidden": false, "pwls": 6, "link_flair_css_class": "tutorial", "downs": 0, "thumbnail_height": null, "top_awarded_type": null, "hide_score": false, "name": "t3_1uhkicg", "quarantine": false, "link_flair_text_color": "dark", "upvote_ratio": 0.7, "author_flair_background_color": null, "subreddit_type": "public", "ups": 10, "total_awards_received": 0, "media_embed": {}, "thumbnail_width": null, "author_flair_template_id": null, "is_original_content": false, "user_reports": [], "secure_media": null, "is_reddit_media_domain": false, "is_meta": false, "category": null, "secure_media_embed": {}, "link_flair_text": "Tutorial", "can_mod_post": false, "score": 10, "approved_by": null, "is_created_from_ads_ui": false, "author_premium": false, "thumbnail": "self", "edited": false, "author_flair_css_class": null, "author_flair_richtext": [], "gildings": {}, "content_categories": null, "is_self": true, "mod_note": null, "created": 1782611904.0, "link_flair_type": "richtext", "wls": 6, "removed_by_category": null, "banned_by": null, "author_flair_type": "text", "domain": "self.Python", "allow_live_comments": false, "selftext_html": "", "likes": null, "suggested_sort": null, "banned_at_utc": null, "view_count": null, "archived": false, "no_follow": false, "is_crosspostable": false, "pinned": false, "over_18": false, "all_awardings": [], "awarders": [], "media_only": false, "link_flair_template_id": "7987a74c-04d8-11eb-84ca-0e0ac8b5a78f", "can_gild": false, "spoiler": false, "locked": false, "author_flair_text": null, "treatment_tags": [], "visited": false, "removed_by": null, "num_reports": null, "distinguished": null, "subreddit_id": "t5_2qh0y", "author_is_blocked": false, "mod_reason_by": null, "removal_reason": null, "link_flair_background_color": "#dadada", "id": "1uhkicg", "is_robot_indexable": true, "report_reasons": null, "author": "DataBaeBee", "discussion_type": null, "num_comments": 8, "send_replies": true, "contest_mode": false, "mod_reports": [], "author_patreon_flair": false, "author_flair_text_color": null, "permalink": "/r/Python/comments/1uhkicg/neural_sorting_algorithms_gumbelsinkhorn_networks/", "stickied": false, "url": "https://www.reddit.com/r/Python/comments/1uhkicg/neural_sorting_algorithms_gumbelsinkhorn_networks/", "subreddit_subscribers": 1493425, "created_utc": 1782611904.0, "num_crossposts": 2, "media": null, "is_video": false}}, {"kind": "t3", "data": {"approved_at_utc": null, "subreddit": "Python", "selftext": "# Weekly Thread: What's Everyone Working On This Week? \ud83d\udee0\ufe0f\n\nHello r/Python! It's time to share what you've been working on! Whether it's a work-in-progress, a completed masterpiece, or just a rough idea, let us know what you're up to!\n\n# How it Works:\n\n1. **Show & Tell**: Share your current projects, completed works, or future ideas.\n2. **Discuss**: Get feedback, find collaborators, or just chat about your project.\n3. **Inspire**: Your project might inspire someone else, just as you might get inspired here.\n\n# Guidelines:\n\n* Feel free to include as many details as you'd like. Code snippets, screenshots, and links are all welcome.\n* Whether it's your job, your hobby, or your passion project, all Python-related work is welcome here.\n\n# Example Shares:\n\n1. **Machine Learning Model**: Working on a ML model to predict stock prices. Just cracked a 90% accuracy rate!\n2. **Web Scraping**: Built a script to scrape and analyze news articles. It's helped me understand media bias better.\n3. **Automation**: Automated my home lighting with Python and Raspberry Pi. My life has never been easier!\n\nLet's build and grow together! Share your journey and learn from others. Happy coding! \ud83c\udf1f", "author_fullname": "t2_6l4z3", "saved": false, "mod_reason_title": null, "gilded": 0, "clicked": false, "title": "Sunday Daily Thread: What's everyone working on this week?", "link_flair_richtext": [{"a": ":pythonLogo:", "e": "emoji", "u": "https://emoji.redditmedia.com/8yxdpg6xxnr71_t5_2qh0y/pythonLogo"}, {"e": "text", "t": " Daily Thread"}], "subreddit_name_prefixed": "r/Python", "hidden": false, "pwls": 6, "link_flair_css_class": "daily-thread", "downs": 0, "thumbnail_height": null, "top_awarded_type": null, "hide_score": false, "name": "t3_1uhhza7", "quarantine": false, "link_flair_text_color": "light", "upvote_ratio": 0.74, "author_flair_background_color": null, "subreddit_type": "public", "ups": 5, "total_awards_received": 0, "media_embed": {}, "thumbnail_width": null, "author_flair_template_id": null, "is_original_content": false, "user_reports": [], "secure_media": null, "is_reddit_media_domain": false, "is_meta": false, "category": null, "secure_media_embed": {}, "link_flair_text": ":pythonLogo: Daily Thread", "can_mod_post": false, "score": 5, "approved_by": null, "is_created_from_ads_ui": false, "author_premium": true, "thumbnail": "self", "edited": false, "author_flair_css_class": null, "author_flair_richtext": [], "gildings": {}, "content_categories": null, "is_self": true, "mod_note": null, "created": 1782604808.0, "link_flair_type": "richtext", "wls": 6, "removed_by_category": null, "banned_by": null, "author_flair_type": "text", "domain": "self.Python", "allow_live_comments": false, "selftext_html": "Weekly Thread: What's Everyone Working On This Week? \ud83d\udee0\ufe0f
\n\n
Hello r/Python! It's time to share what you've been working on! Whether it's a work-in-progress, a completed masterpiece, or just a rough idea, let us know what you're up to!
\n\n
How it Works:
\n\n
\n- Show & Tell: Share your current projects, completed works, or future ideas.
\n- Discuss: Get feedback, find collaborators, or just chat about your project.
\n- Inspire: Your project might inspire someone else, just as you might get inspired here.
\n
\n\n
Guidelines:
\n\n
\n- Feel free to include as many details as you'd like. Code snippets, screenshots, and links are all welcome.
\n- Whether it's your job, your hobby, or your passion project, all Python-related work is welcome here.
\n
\n\n
Example Shares:
\n\n
\n- Machine Learning Model: Working on a ML model to predict stock prices. Just cracked a 90% accuracy rate!
\n- Web Scraping: Built a script to scrape and analyze news articles. It's helped me understand media bias better.
\n- Automation: Automated my home lighting with Python and Raspberry Pi. My life has never been easier!
\n
\n\n
Let's build and grow together! Share your journey and learn from others. Happy coding! \ud83c\udf1f
\n
", "likes": null, "suggested_sort": null, "banned_at_utc": null, "view_count": null, "archived": false, "no_follow": false, "is_crosspostable": false, "pinned": false, "over_18": false, "all_awardings": [], "awarders": [], "media_only": false, "link_flair_template_id": "6c024934-de3f-11ea-a05a-0ea86b2be9a1", "can_gild": false, "spoiler": false, "locked": false, "author_flair_text": null, "treatment_tags": [], "visited": false, "removed_by": null, "num_reports": null, "distinguished": "moderator", "subreddit_id": "t5_2qh0y", "author_is_blocked": false, "mod_reason_by": null, "removal_reason": null, "link_flair_background_color": "#00a6a5", "id": "1uhhza7", "is_robot_indexable": true, "report_reasons": null, "author": "AutoModerator", "discussion_type": null, "num_comments": 5, "send_replies": false, "contest_mode": false, "mod_reports": [], "author_patreon_flair": false, "author_flair_text_color": null, "permalink": "/r/Python/comments/1uhhza7/sunday_daily_thread_whats_everyone_working_on/", "stickied": false, "url": "https://www.reddit.com/r/Python/comments/1uhhza7/sunday_daily_thread_whats_everyone_working_on/", "subreddit_subscribers": 1493425, "created_utc": 1782604808.0, "num_crossposts": 0, "media": null, "is_video": false}}, {"kind": "t3", "data": {"approved_at_utc": null, "subreddit": "Python", "selftext": "Hi guys this tutorial is about handling errors as value in Python or in nerd language monadic error handling pattern in Python using [katharos](https://github.com/kamalfarahani/katharos) library:\n\n[https://theblog.info/posts/handling-errors-as-values-in-python-with-katharos](https://theblog.info/posts/handling-errors-as-values-in-python-with-katharos)", "author_fullname": "t2_rkfihkkzk", "saved": false, "mod_reason_title": null, "gilded": 0, "clicked": false, "title": "Handling Errors as Values in Python with Katharos", "link_flair_richtext": [{"e": "text", "t": "Tutorial"}], "subreddit_name_prefixed": "r/Python", "hidden": false, "pwls": 6, "link_flair_css_class": "tutorial", "downs": 0, "thumbnail_height": null, "top_awarded_type": null, "hide_score": false, "name": "t3_1ugsdwl", "quarantine": false, "link_flair_text_color": "dark", "upvote_ratio": 0.8, "author_flair_background_color": null, "subreddit_type": "public", "ups": 32, "total_awards_received": 0, "media_embed": {}, "thumbnail_width": null, "author_flair_template_id": null, "is_original_content": false, "user_reports": [], "secure_media": null, "is_reddit_media_domain": false, "is_meta": false, "category": null, "secure_media_embed": {}, "link_flair_text": "Tutorial", "can_mod_post": false, "score": 32, "approved_by": null, "is_created_from_ads_ui": false, "author_premium": false, "thumbnail": "self", "edited": false, "author_flair_css_class": null, "author_flair_richtext": [], "gildings": {}, "post_hint": "self", "content_categories": null, "is_self": true, "mod_note": null, "created": 1782532952.0, "link_flair_type": "richtext", "wls": 6, "removed_by_category": null, "banned_by": null, "author_flair_type": "text", "domain": "self.Python", "allow_live_comments": false, "selftext_html": "", "likes": null, "suggested_sort": null, "banned_at_utc": null, "view_count": null, "archived": false, "no_follow": false, "is_crosspostable": false, "pinned": false, "over_18": false, "preview": {"images": [{"source": {"url": "https://external-preview.redd.it/2Eh5ntKTVDMhEisUeP53EhuqwJJIX0ynlVvClZhlpoc.png?auto=webp&s=e1b494e288c1332109f2282e0eda050c121c7f94", "width": 1200, "height": 600}, "resolutions": [{"url": "https://external-preview.redd.it/2Eh5ntKTVDMhEisUeP53EhuqwJJIX0ynlVvClZhlpoc.png?width=108&crop=smart&auto=webp&s=ce16fd58cc96586a6f4e09bca243f41637f64836", "width": 108, "height": 54}, {"url": "https://external-preview.redd.it/2Eh5ntKTVDMhEisUeP53EhuqwJJIX0ynlVvClZhlpoc.png?width=216&crop=smart&auto=webp&s=c3fb804da74b957b5369749521851ac924019025", "width": 216, "height": 108}, {"url": "https://external-preview.redd.it/2Eh5ntKTVDMhEisUeP53EhuqwJJIX0ynlVvClZhlpoc.png?width=320&crop=smart&auto=webp&s=f77c73faba71e3855e963638b6e281ae8ba9326b", "width": 320, "height": 160}, {"url": "https://external-preview.redd.it/2Eh5ntKTVDMhEisUeP53EhuqwJJIX0ynlVvClZhlpoc.png?width=640&crop=smart&auto=webp&s=12389bfb3289b1adbe89c931c1868cfb229f14cd", "width": 640, "height": 320}, {"url": "https://external-preview.redd.it/2Eh5ntKTVDMhEisUeP53EhuqwJJIX0ynlVvClZhlpoc.png?width=960&crop=smart&auto=webp&s=d129a03ff5a59c64480e409707497af6c212c840", "width": 960, "height": 480}, {"url": "https://external-preview.redd.it/2Eh5ntKTVDMhEisUeP53EhuqwJJIX0ynlVvClZhlpoc.png?width=1080&crop=smart&auto=webp&s=db5f489c84a30dd6dbc69accc931aebd60168702", "width": 1080, "height": 540}], "variants": {}, "id": "2Eh5ntKTVDMhEisUeP53EhuqwJJIX0ynlVvClZhlpoc"}], "enabled": false}, "all_awardings": [], "awarders": [], "media_only": false, "link_flair_template_id": "7987a74c-04d8-11eb-84ca-0e0ac8b5a78f", "can_gild": false, "spoiler": false, "locked": false, "author_flair_text": null, "treatment_tags": [], "visited": false, "removed_by": null, "num_reports": null, "distinguished": null, "subreddit_id": "t5_2qh0y", "author_is_blocked": false, "mod_reason_by": null, "removal_reason": null, "link_flair_background_color": "#dadada", "id": "1ugsdwl", "is_robot_indexable": true, "report_reasons": null, "author": "EntryNo8040", "discussion_type": null, "num_comments": 9, "send_replies": true, "contest_mode": false, "mod_reports": [], "author_patreon_flair": false, "author_flair_text_color": null, "permalink": "/r/Python/comments/1ugsdwl/handling_errors_as_values_in_python_with_katharos/", "stickied": false, "url": "https://www.reddit.com/r/Python/comments/1ugsdwl/handling_errors_as_values_in_python_with_katharos/", "subreddit_subscribers": 1493425, "created_utc": 1782532952.0, "num_crossposts": 2, "media": null, "is_video": false}}], "before": null}}
\ No newline at end of file