<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Tech by Choice</title>
    <description>The latest articles on DEV Community by Tech by Choice (@techbychoiceorg).</description>
    <link>https://dev.to/techbychoiceorg</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Forganization%2Fprofile_image%2F7323%2F619cb408-ba1a-432b-9fd9-2bff0419f21e.png</url>
      <title>DEV Community: Tech by Choice</title>
      <link>https://dev.to/techbychoiceorg</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/techbychoiceorg"/>
    <language>en</language>
    <item>
      <title>Debug Mode: Django Docker Pycharm</title>
      <dc:creator>Valerie Phoenix ✊🏾</dc:creator>
      <pubDate>Sat, 07 Sep 2024 02:06:20 +0000</pubDate>
      <link>https://dev.to/techbychoiceorg/debug-mode-django-docker-pycharm-i8d</link>
      <guid>https://dev.to/techbychoiceorg/debug-mode-django-docker-pycharm-i8d</guid>
      <description>&lt;p&gt;Getting your local setup to debug the code you're writing properly takes more time than any dev would like to admit. And let's not forget this is mostly a one-and-done setup, so if we don't write it down, we won't remember. This post is here to solve that exact issue!  Let this serve as a written reminder of how to get your local dev environment up and running.&lt;/p&gt;

&lt;h3&gt;
  
  
  Prerequisites:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;PyCharm Professional (for Docker support)&lt;/li&gt;
&lt;li&gt;Docker and Docker Compose&lt;/li&gt;
&lt;li&gt;Django REST Framework (DRF) Application&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;This post will not cover details about the Django, Docker, or Docker composer setup outside of the updates needed for debug mode. It assumes you already have a working knowledge of how to get that part to work.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Step 1: Dockerfile Setup for Debugging
&lt;/h2&gt;

&lt;p&gt;Set up your Dockerfile to run in dev mode and allow connections from the PyCharm debugger.&lt;/p&gt;

&lt;p&gt;Below is an example Dockerfile:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Builder stage
FROM python:3.9-slim as builder

RUN chmod 1777 /tmp

# Install system dependencies
RUN apt-get update &amp;amp;&amp;amp; apt-get install -y \
    libpq-dev \
    build-essential

WORKDIR /app

# Copy the requirements file into the container
COPY requirements.txt /app/
RUN pip install --no-cache-dir -r requirements.txt &amp;gt; pip_install.log

# Copy the current directory contents into the container
COPY . /app

# Collect static files
RUN python manage.py collectstatic --noinput

# Final stage
FROM python:3.9-slim

# Set environment variables
ENV PYTHONUNBUFFERED=1
ENV DJANGO_SETTINGS_MODULE=template.settings.development

# Set work directory
WORKDIR /app

# Copy files from the builder stage
COPY --from=builder /app /app

# Install pydevd-pycharm for remote debugging and gunicorn for serving
RUN pip install gunicorn pydevd-pycharm==241.17890.14 psycopg2-binary

# Expose necessary ports
EXPOSE 8000 5679  # Web app port and debug port

# Entry point for the container
ENTRYPOINT ["sh", "-c", "python manage.py runserver 0.0.0.0:8000"]

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Things to keep in mind about this code &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;241.17890.14&lt;/code&gt; in &lt;code&gt;pydevd-pycharm==241.17890.14&lt;/code&gt; is going to be different depending on the version of Pycharm you have&lt;/li&gt;
&lt;li&gt;We're exposing both 8000 (the web server port) and 5679 (the debugger port) for external access.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Step 2: Docker Compose Configuration
&lt;/h2&gt;

&lt;p&gt;Let's get our docker-compose.yml file going to configure the web service (Django app) along with the database and other services.&lt;/p&gt;

&lt;p&gt;Here is a sample docker-compose.yml:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;version: '3'

services:
  web:
    environment:
      - DJANGO_ENVIRONMENT=development
      - DB_HOST=host.docker.internal
    build:
      context: .
    command: &amp;gt;
      sh -c "python manage.py migrate &amp;amp;&amp;amp;
             python manage.py collectstatic --noinput &amp;amp;&amp;amp;
             python manage.py runserver 0.0.0.0:8000"
    volumes:
      - .:/app
    ports:
      - "8000:8000"   # Expose web port
      - "5679:5679"   # Expose debugger port
    extra_hosts:
      - "host.docker.internal:host-gateway"
  db:
    image: postgres:13
    environment:
      - POSTGRES_DB=${DB_NAME}
      - POSTGRES_USER=${DB_USER}
      - POSTGRES_PASSWORD=${DB_PASSWORD}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's jump into the code breakdown&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;We're mapping port 8000 for the web server and port 5679 for the PyCharm debugger.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;extra_hosts&lt;/code&gt; ensures your Docker container can communicate with the host machine using host.docker.internal.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Step 3: Configure PyCharm for Debugging
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Create a Python Debug Server Configuration:&lt;/li&gt;
&lt;li&gt;In PyCharm navigate to &lt;code&gt;Run ➡️ Edit Configurations&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Click the + button and select Python Debug Server.&lt;/li&gt;
&lt;li&gt;Set the Host to &lt;code&gt;0.0.0.0&lt;/code&gt; or your local machine’s IP address.&lt;/li&gt;
&lt;li&gt;Set the Port to &lt;code&gt;5679&lt;/code&gt; (or the one you expose in your Docker setup).&lt;/li&gt;
&lt;li&gt;&lt;p&gt;And hit Save!&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Start the Debugger Server:&lt;br&gt;
Start the PyCharm debugger by clicking the Debug button (green bug icon). This will start listening on the port we set.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Step 4: Add Remote Debugging Code to Django
&lt;/h2&gt;

&lt;p&gt;In your Django project, you'll need to add the following code in your &lt;code&gt;manage.py&lt;/code&gt; or &lt;code&gt;wsgi.py&lt;/code&gt; to connect to the PyCharm debugger:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import pydevd_pycharm

# Connect to the PyCharm debug server
pydevd_pycharm.settrace('host.docker.internal', port=5679, stdoutToServer=True, stderrToServer=True, suspend=False)

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This snippet tells your Django app to connect back to the PyCharm debugger running on your host machine. host.docker.internal resolves to the host machine in Docker, and port=5679 matches the one we exposed earlier.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 5: Run Docker and Debug
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Build and Run Docker:
Run the following command to start your containers:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;docker-compose up --build
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will build the Docker image and start the services, including Django running in development mode.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Set Breakpoints:&lt;/strong&gt;&lt;br&gt;
Set breakpoints in your Django code within PyCharm. The breakpoints should work because your container will connect to the PyCharm debug server running on port 5679.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Trigger Your Code:&lt;/strong&gt;&lt;br&gt;
Now, trigger any HTTP request in your Django REST Framework API. When the code hits the breakpoint, PyCharm will pause execution, allowing you to inspect the current state and step through the code.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 6: Troubleshooting
&lt;/h2&gt;

&lt;p&gt;If you encounter the error &lt;code&gt;bind: address already in use&lt;/code&gt; while running Docker, another process already uses port 5679. In this case, you can:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Stop the PyCharm debugger and restart Docker.&lt;/li&gt;
&lt;li&gt;Change the port in your docker-compose.yml and PyCharm configuration to avoid conflicts.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;This is the setup I use to run my Django REST Framework application in development mode inside a Docker container using PyCharm’s powerful debugger. This setup helps me debug my backend code by stepping through the code line by line, all locally.&lt;/p&gt;

&lt;p&gt;By setting up your Docker container to communicate with PyCharm, you simplify writing, testing, and debugging your Django application, making it easier to write code!&lt;/p&gt;

&lt;p&gt;Have fun breaking your code!&lt;/p&gt;

</description>
      <category>python</category>
      <category>development</category>
      <category>docker</category>
      <category>pycharm</category>
    </item>
    <item>
      <title>Django, Celery, and Redis on Railway</title>
      <dc:creator>Valerie Phoenix ✊🏾</dc:creator>
      <pubDate>Thu, 03 Aug 2023 17:29:18 +0000</pubDate>
      <link>https://dev.to/techbychoiceorg/django-celery-and-redis-on-railway-214h</link>
      <guid>https://dev.to/techbychoiceorg/django-celery-and-redis-on-railway-214h</guid>
      <description>&lt;h2&gt;
  
  
  &lt;strong&gt;Introduction&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Using Django Rest Framework, Celery, and Redis I created a &lt;a href="https://quiz.techbychoice.org/" rel="noopener noreferrer"&gt;personalized quiz to help people find roles in tech they would like&lt;/a&gt;. The app asks you questions and creates a custom image with your results that needs time to process in the background, so I leverage Celery and Redis to get this work done! &lt;/p&gt;

&lt;p&gt;Now the app took me a day to build, but a week to deploy to production. Why? The age old story of hard-to-find, or nonexistent documentation. To break the broken cycle in tech I’ve created this tutorial to cover the following steps:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;How to deploy and set up Redis on Railway &lt;/li&gt;
&lt;li&gt;How to connect your Django server to your Redis server on Railway&lt;/li&gt;
&lt;li&gt;How to run your Celery workers during the build&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This blog will &lt;strong&gt;not&lt;/strong&gt; cover: &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The basics of Python &lt;/li&gt;
&lt;li&gt;Getting started with Django Rest Framework&lt;/li&gt;
&lt;li&gt;Getting started with Celery&lt;/li&gt;
&lt;li&gt;Getting started with Redis&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Prerequisites&lt;/strong&gt;
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Skills needed: Basic knowledge of Django, Redis, Celery&lt;/li&gt;
&lt;li&gt;Tools required: A Django Project that’s set up to use Redis &amp;amp; Celery&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Or you can just read along for fun if you’re not going to build with the tutorial! &lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Section 2: Project Overview&lt;/strong&gt;
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Below is a simplified overview of the project structure so you can have a better understanding of how the project is structured

&lt;ol&gt;
&lt;li&gt;For this blog, I’ve bolded the files that we’ll focus on to make sure
&lt;/li&gt;
&lt;/ol&gt;


&lt;/li&gt;

&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;tbc&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;
&lt;span class="err"&gt;├──&lt;/span&gt; &lt;span class="n"&gt;manage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;py&lt;/span&gt;
&lt;span class="err"&gt;├──&lt;/span&gt; &lt;span class="err"&gt;➕&lt;/span&gt; &lt;span class="n"&gt;Procfile&lt;/span&gt;
&lt;span class="err"&gt;├──&lt;/span&gt; &lt;span class="n"&gt;tbc&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;
&lt;span class="err"&gt;│&lt;/span&gt;   &lt;span class="err"&gt;├──&lt;/span&gt; &lt;span class="n"&gt;__init__&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;py&lt;/span&gt;
&lt;span class="err"&gt;│&lt;/span&gt;   &lt;span class="err"&gt;├──&lt;/span&gt; &lt;span class="n"&gt;asgi&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;py&lt;/span&gt;
&lt;span class="err"&gt;│&lt;/span&gt;   &lt;span class="err"&gt;├──&lt;/span&gt; &lt;span class="n"&gt;settings&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;py&lt;/span&gt;
&lt;span class="err"&gt;│&lt;/span&gt;   &lt;span class="err"&gt;├──&lt;/span&gt; &lt;span class="n"&gt;urls&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;py&lt;/span&gt;
&lt;span class="err"&gt;│&lt;/span&gt;   &lt;span class="err"&gt;└──&lt;/span&gt; &lt;span class="err"&gt;➕&lt;/span&gt; &lt;span class="n"&gt;celery&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;py&lt;/span&gt;
&lt;span class="err"&gt;│&lt;/span&gt;   &lt;span class="err"&gt;└──&lt;/span&gt; &lt;span class="n"&gt;wsgi&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;py&lt;/span&gt;
&lt;span class="err"&gt;└──&lt;/span&gt; &lt;span class="n"&gt;quiz&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;
    &lt;span class="err"&gt;├──&lt;/span&gt; &lt;span class="n"&gt;migrations&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;
    &lt;span class="err"&gt;│&lt;/span&gt;   &lt;span class="err"&gt;└──&lt;/span&gt; &lt;span class="n"&gt;__init__&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;py&lt;/span&gt;
    &lt;span class="err"&gt;├──&lt;/span&gt; &lt;span class="n"&gt;__init__&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;py&lt;/span&gt;
    &lt;span class="err"&gt;├──&lt;/span&gt; &lt;span class="n"&gt;admin&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;py&lt;/span&gt;
    &lt;span class="err"&gt;├──&lt;/span&gt; &lt;span class="n"&gt;apps&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;py&lt;/span&gt;
    &lt;span class="err"&gt;├──&lt;/span&gt; &lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;py&lt;/span&gt;
    &lt;span class="err"&gt;├──&lt;/span&gt; &lt;span class="n"&gt;serializers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;py&lt;/span&gt;
    &lt;span class="err"&gt;├──&lt;/span&gt; &lt;span class="err"&gt;➕&lt;/span&gt; &lt;span class="n"&gt;tasks&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;py&lt;/span&gt;
    &lt;span class="err"&gt;├──&lt;/span&gt; &lt;span class="n"&gt;tests&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;py&lt;/span&gt;
    &lt;span class="err"&gt;├──&lt;/span&gt; &lt;span class="n"&gt;urls&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;py&lt;/span&gt;
    &lt;span class="err"&gt;└──&lt;/span&gt; &lt;span class="n"&gt;views&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;py&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;celery.py&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;os&lt;/span&gt;

&lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="nx"&gt;celery&lt;/span&gt; &lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Celery&lt;/span&gt;

&lt;span class="err"&gt;#&lt;/span&gt; &lt;span class="nb"&gt;Set&lt;/span&gt; &lt;span class="nx"&gt;the&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;Django&lt;/span&gt; &lt;span class="nx"&gt;settings&lt;/span&gt; &lt;span class="nx"&gt;module&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="nx"&gt;the&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;celery&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="nx"&gt;program&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;
&lt;span class="nx"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;environ&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setdefault&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;DJANGO_SETTINGS_MODULE&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;tbc.settings&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nx"&gt;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Celery&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;tasks&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
             &lt;span class="nx"&gt;backend&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nx"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getenv&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;REDIS_URL&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
             &lt;span class="nx"&gt;broker&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nx"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getenv&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;REDIS_URL&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
             &lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="err"&gt;#&lt;/span&gt; &lt;span class="nx"&gt;Using&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt; &lt;span class="nx"&gt;here&lt;/span&gt; &lt;span class="nx"&gt;means&lt;/span&gt; &lt;span class="nx"&gt;the&lt;/span&gt; &lt;span class="nx"&gt;worker&lt;/span&gt; &lt;span class="nx"&gt;doesn&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;t have to serialize
# the configuration object to child processes.
# - namespace=&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="nx"&gt;CELERY&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt; means all celery-related configuration keys
#   should have a `CELERY_` prefix.
app.config_from_object(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="nx"&gt;django&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;conf&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nx"&gt;settings&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;, namespace=&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="nx"&gt;CELERY&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;)

# Load task modules from all registered Django apps.
app.autodiscover_tasks()

@app.task(bind=True)
def debug_task(self):
    print(f&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="nx"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nb"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;request&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;r&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;)
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  &lt;strong&gt;Setting Up Railway&lt;/strong&gt;
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Create a Redis Server in Railways
&lt;/h3&gt;

&lt;p&gt;Now that the files are all ready for different environments, let’s head over to the project in Railway to add a new Redis instance.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;To get started, head over to your Railway dashboard and select the project you would like to add your Redis setup to. Once in the project, click '+ New' to get the service dropdown.&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fs0nc9scypk92bln6mx8n.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fs0nc9scypk92bln6mx8n.png" alt="Screenshot of railway dashboard where you click the '+ New' button to create a new services" width="614" height="222"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;From the dropdown, you want to select Redis by either typing in Redis to have it pop up or selecting the database to find the Redis option.&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffmgzb7hhl0cu9jntg85e.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffmgzb7hhl0cu9jntg85e.png" alt="Screenshot of redis typed into the search box and the user clicking on the 'Add Redis' option" width="800" height="482"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Adding a Railways Reference Variable
&lt;/h3&gt;

&lt;p&gt;In our code, we use the &lt;code&gt;REDIS_URL&lt;/code&gt; environment variable in our &lt;code&gt;[celery.py](http://celeary.py)&lt;/code&gt; file so our project can use different Redis URLs for each environment we’re working in.&lt;/p&gt;

&lt;p&gt;For the production environment, we want our &lt;code&gt;REDIS_URL&lt;/code&gt; to connect to the Redis server we created in the previous step. To do this we leverage the Railway Reference variable for Redis_URL.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;ℹ️ The way I think of Railway Reference variables is a quick way to add variables for Railway-based services without having to type or copy and paste the value because the Railway defines the value for you! Want to learn more about this topic? Check out their &lt;a href="https://docs.railway.app/develop/variables" rel="noopener noreferrer"&gt;documentation on variables&lt;/a&gt; here.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Faiow2m1v3zzxc0l6nw73.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Faiow2m1v3zzxc0l6nw73.png" alt="Screenshot of user adding Redis_Url variable to the environment setting from a list of predefined variables from Railway" width="800" height="511"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Running and Monitoring Celery Tasks In Railway&lt;/strong&gt;
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;To run the Celery worker, you’ll need to update your &lt;code&gt;Procfile&lt;/code&gt; to look like this:&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;web&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;celery&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;A&lt;/span&gt; &lt;span class="n"&gt;tbc&lt;/span&gt; &lt;span class="n"&gt;worker&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;loglevel&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;info&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;python&lt;/span&gt; &lt;span class="n"&gt;manage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;py&lt;/span&gt; &lt;span class="n"&gt;migrate&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;gunicorn&lt;/span&gt; &lt;span class="n"&gt;tbc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;wsgi&lt;/span&gt;  &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;bind&lt;/span&gt; &lt;span class="mf"&gt;0.0&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mf"&gt;0.0&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="n"&gt;PORT&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;


&lt;p&gt;&lt;strong&gt;What is this doing?&lt;/strong&gt;&lt;br&gt;
This allows Railway to run the celery worker when the system deploys the site. Without this task running your Django app won’t be able to connect with the celery worker.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;ℹ️ You may be thinking “hey, I have to start the Redis server when I’m running this on my local. Don’t I have to do the same for production?” And the answer is no, because Railway does it for you.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Why are we updating the  &lt;code&gt;Procfile&lt;/code&gt; file?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;When working in our local files we start our Django and Redis server before we run our celery worker and make sure we run all of our migrations. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What is a &lt;code&gt;Procfile&lt;/code&gt; file?&lt;/strong&gt;&lt;br&gt;
The &lt;code&gt;Procfile&lt;/code&gt; is how we tell the server how to run these commands and more after Railway kicks off the server.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What does the command we add mean?&lt;/strong&gt;&lt;br&gt;
By adding &lt;strong&gt;&lt;code&gt;celery -A tbc worker --loglevel=info &amp;amp;&lt;/code&gt;&lt;/strong&gt; before the other commands you’re telling the Railway to run the Celery so your task can run. One thing to call out here is the order of tasks is important. Add the celery details first to avoid possible build errors you could run into if celery isn’t running during the app building.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;ℹ️ If you’re familiar with Procfile files, you might be used to seeing the file set up like it is below with the celery details under the worker. The reason we’re placing the worker details on the web line is because Railway only reads commands under the web.&lt;br&gt;
&lt;/p&gt;


&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;```python
web: python manage.py migrate &amp;amp;&amp;amp; gunicorn tbc.wsgi
worker: celery -A tbc worker --loglevel=info
```
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  &lt;strong&gt;Ready for Testing&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;At this stage everything is connected and ready to run to be tested in production! If you've added any logging to any of your task, you'll see this information show up in your Django server in railway.&lt;/p&gt;

&lt;p&gt;If you hit all of your workflows and everything is working as expected, congratulations because you did it! &lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Conclusion&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;In this blog we’ve set up our prod Railway environment to work with Django, Redis, and Celery!&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;We’ve been able to cover 

&lt;ol&gt;
&lt;li&gt;How to set up our project to support the production environment&lt;/li&gt;
&lt;li&gt;Cover the steps needed to create a Redis server in Railway&lt;/li&gt;
&lt;li&gt;How to connect your Django server in production to your  Redis server&lt;/li&gt;
&lt;/ol&gt;


&lt;/li&gt;

&lt;/ol&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Further Resources&lt;/strong&gt;
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Links to documentation and more advanced guides

&lt;ol&gt;
&lt;li&gt;&lt;a href="https://redis.io/docs/getting-started/" rel="noopener noreferrer"&gt;Redis Documentation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.railway.app/" rel="noopener noreferrer"&gt;Railway Documentation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://episyche.com/blog/how-to-run-periodic-tasks-in-django-using-celery" rel="noopener noreferrer"&gt;Django Celery Redis Guide I found helpful&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;


&lt;/li&gt;

&lt;/ol&gt;

&lt;p&gt;If you made it this far, I want to just say thanks for following along! Would love to hear your feedback and thoughts on this blog post.&lt;/p&gt;

</description>
      <category>django</category>
      <category>celery</category>
      <category>redis</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>GM from Tech by Choice</title>
      <dc:creator>Valerie Phoenix ✊🏾</dc:creator>
      <pubDate>Fri, 19 Nov 2021 22:27:06 +0000</pubDate>
      <link>https://dev.to/techbychoiceorg/gm-from-tech-by-choice-eo1</link>
      <guid>https://dev.to/techbychoiceorg/gm-from-tech-by-choice-eo1</guid>
      <description>&lt;p&gt;The mission of Tech by Choice should be one that everyone supports and benefits from. To see our vision come true, we must be transparent and community-driven. There should never be one person filling every role to keep things going.&lt;/p&gt;

&lt;p&gt;Being a membership-based nonprofit with a flat org structure is not enough to support the vision I have for the Tech by Choice community. I spent the last year searching for ways I can genuinely help and sustain the growth of Tech by Choice. To my surprise web 3 has offered a solution through its support of Decentralized Autonomous Nonprofit organizations &lt;a href="https://medium.com/blockchannel/what-is-a-dao-how-do-they-benefit-consumers-f7a0a862f3dc" rel="noopener noreferrer"&gt;Read more about DAOs here&lt;/a&gt;. We’ve partnered with a Black female NFT artist during the giving season that will create a generative art project to highlight the importance community has with ensuring tech is diverse &lt;a href="http://www.communiteanft.art/" rel="noopener noreferrer"&gt;view the project here&lt;/a&gt;. We will use a percentage of the funds raised to work with a DAO consultant to support the structural change of Tech by Choice. We will continue to behold our nonprofit status, but our structure internally will change to better support the community and our mission.&lt;/p&gt;

&lt;p&gt;Historically when an organization makes a significant change like this, people fear that they will water down what they do. For us, this is the complete opposite. This change will help us support our members more directly and communally. To prove this point, the very first proposal I will submit for our community is to find a way to help our members deal with the &lt;a href="https://www.vox.com/the-highlight/22323477/personal-finance-black-tax-racial-wealth-gap" rel="noopener noreferrer"&gt;Black Tax&lt;/a&gt;. This is a topic I’ve been vocal about and one that I know the Tech by Choice community has brought up as well. Through this new structure, we will find a way to elevate this burden for our members. &lt;/p&gt;

&lt;p&gt;This is just one example from me, a single member of the community. I know together we will create programs and funds that will support several burdens our members face. But to get there, we have to do this together.   &lt;/p&gt;

&lt;p&gt;The Tech by Choice community is one I care for deeply. I will always make time for our mission to ensure marginalized people know tech has a space for them. I hope those who read this message will see this change as me shifting my power and status within this organization as a way to keep it going. I hope people do not make this change as I walk away from giving up on our community.&lt;/p&gt;

&lt;p&gt;Valerie Phoenix &lt;br&gt;
Founder of Tech by Choice&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Where We Stand</title>
      <dc:creator>Valerie Phoenix ✊🏾</dc:creator>
      <pubDate>Sun, 07 Jun 2020 11:11:01 +0000</pubDate>
      <link>https://dev.to/techbychoiceorg/where-we-stand-15b2</link>
      <guid>https://dev.to/techbychoiceorg/where-we-stand-15b2</guid>
      <description>&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fuh9es2z9i7nhteyrexm2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fuh9es2z9i7nhteyrexm2.png" alt="illustration of black man with fist in the air standing next to a black women with a sign that reads 'Black Lives Matter'" width="800" height="800"&gt;&lt;/a&gt;&lt;br&gt;
If anyone has any question on where this organization stands in regards to the recent protest over the countless lives lost due to systemic racism that plagues our globe, I'm afraid you don't understand &lt;a href="http://techbychoice.org/" rel="noopener noreferrer"&gt;Tech By Choice&lt;/a&gt;. Our mission. Our values. Our community. Our leadership. Our board.&lt;/p&gt;

&lt;p&gt;Our current social unrest did not start with Emmett Till and did not end with George Floyd. The black lives lost during the week of May 25 was the tipping point of the unjust treatment of Black people that has been going on for the last 400+ years. No amount of words can express the hurt, anger, and fear our community is going through.&lt;/p&gt;

&lt;p&gt;We are all grieving.&lt;/p&gt;

&lt;p&gt;Recent events had me question several things. How can we thrive if they don't think we matter? If they don't think we deserve civil rights? If they don't see us?&lt;/p&gt;

&lt;p&gt;To me, the best part of being black in tech has been using tech to enhance my ability to turn nothing into something. This is why Tech By Choice is on a mission to ensure underserved adults know they can enter, stay, and thrive in STEAM (Science Technology Art Engineering and Math) because we have always thrived. And always will.&lt;/p&gt;

&lt;p&gt;But we can't lose hope.&lt;/p&gt;

&lt;p&gt;Do not let our silence be confused with being complicit. We stand with every person protesting. They are our hope.&lt;/p&gt;

&lt;p&gt;Our leadership and board are working harder than ever to keep this hope going. Stay tuned for the action we take.&lt;/p&gt;

&lt;p&gt;In the meantime remember statements can easily become empty promises. Hold us, and others, accountable to these statements.&lt;/p&gt;

&lt;p&gt;If you feel inclined to donate to organizations, we ask that you do your homework and lookup these organizations on sites like Guidestar. Find organizations that are doing the work but don't have the funding that well-known organizations have.&lt;/p&gt;

&lt;p&gt;Valerie&lt;br&gt;
Founder &amp;amp; CEO&lt;br&gt;
Tech By Choice&lt;/p&gt;

&lt;h5&gt;
  
  
  #BlackLivesMatter #SayHerName
&lt;/h5&gt;

&lt;h3&gt;
  
  
  Resources for people grieving
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Mental Health
&lt;/h4&gt;

&lt;p&gt;&lt;a href="https://therapyforblackgirls.com/" rel="noopener noreferrer"&gt;Therapy For Black Girls&lt;/a&gt;&lt;br&gt;
&lt;a href="https://therapyforblackmen.org/" rel="noopener noreferrer"&gt;Therapy For Black Men&lt;/a&gt;&lt;br&gt;
&lt;a href="https://blackmentalhealthmatters.carrd.co/" rel="noopener noreferrer"&gt;Black Mental Health Matters&lt;/a&gt;&lt;br&gt;
&lt;a href="https://thelovelandfoundation.org/" rel="noopener noreferrer"&gt;The Loveland Foundation&lt;/a&gt;&lt;br&gt;
&lt;a href="https://www.psychologytoday.com/us/therapists" rel="noopener noreferrer"&gt;Psychology Today&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  How to recharge
&lt;/h4&gt;

&lt;p&gt;&lt;a href="https://hashtagprotectyourenergy.weebly.com/" rel="noopener noreferrer"&gt;Protect Your Energy&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Protesting
&lt;/h4&gt;

&lt;p&gt;&lt;a href="https://moreblminfo.carrd.co/#prosafety" rel="noopener noreferrer"&gt;Tips&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Additional Learning
&lt;/h4&gt;

&lt;p&gt;&lt;a href="https://docs.google.com/document/u/2/d/1-4BqwazBjN0DF2zBjwJR5i1hGd6XQ8OVabgTgg0jkas/mobilebasic" rel="noopener noreferrer"&gt;Resources for non Black folks who don't know where to start&lt;/a&gt;&lt;br&gt;
&lt;a href="https://mappingpoliceviolence.org/" rel="noopener noreferrer"&gt;Mapping Police Violence&lt;/a&gt;&lt;br&gt;
&lt;a href="https://fatalencounters.org/" rel="noopener noreferrer"&gt;Fatal Encounters&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
  </channel>
</rss>
