django-qstash 0.0.14__py3-none-any.whl → 0.1.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of django-qstash might be problematic. Click here for more details.

django_qstash/__init__.py CHANGED
@@ -1,6 +1,6 @@
1
1
  from __future__ import annotations
2
2
 
3
- __version__ = "0.0.14"
3
+ __version__ = "0.1.0"
4
4
 
5
5
  from django_qstash.app import shared_task
6
6
  from django_qstash.app import stashed_task
django_qstash/client.py CHANGED
@@ -1,7 +1,25 @@
1
1
  from __future__ import annotations
2
2
 
3
+ import os
4
+ import warnings
5
+
3
6
  from qstash import QStash
4
7
 
5
8
  from django_qstash.settings import QSTASH_TOKEN
6
9
 
7
- qstash_client = QStash(QSTASH_TOKEN)
10
+ QSTASH_URL = os.environ.get("QSTASH_URL", None)
11
+
12
+
13
+ def init_qstash():
14
+ kwargs = {
15
+ "token": QSTASH_TOKEN,
16
+ }
17
+ if QSTASH_URL is not None:
18
+ warning_msg = f"\n\n\033[93mUsing {QSTASH_URL} as your QStash URL. \
19
+ \nThis configuration should only be used in development.\n\033[0m"
20
+ warnings.warn(warning_msg, RuntimeWarning, stacklevel=2)
21
+ kwargs["base_url"] = QSTASH_URL
22
+ return QStash(**kwargs)
23
+
24
+
25
+ qstash_client = init_qstash()
django_qstash/settings.py CHANGED
@@ -11,7 +11,7 @@ DJANGO_QSTASH_WEBHOOK_PATH = getattr(
11
11
  )
12
12
  if not QSTASH_TOKEN or not DJANGO_QSTASH_DOMAIN:
13
13
  warnings.warn(
14
- "QSTASH_TOKEN and DJANGO_QSTASH_DOMAIN should be set for QStash functionality",
14
+ "DJANGO_SETTINGS_MODULE (settings.py required) requires QSTASH_TOKEN and DJANGO_QSTASH_DOMAIN should be set for QStash functionality",
15
15
  RuntimeWarning,
16
16
  stacklevel=2,
17
17
  )
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: django-qstash
3
- Version: 0.0.14
3
+ Version: 0.1.0
4
4
  Summary: A drop-in replacement for Celery's shared_task with Upstash QStash.
5
5
  Author-email: Justin Mitchel <justin@codingforentrepreneurs.com>
6
6
  Project-URL: Changelog, https://github.com/jmitchel3/django-qstash
@@ -27,11 +27,11 @@ Requires-Dist: django>=4.2
27
27
  Requires-Dist: qstash>=2
28
28
  Requires-Dist: requests>=2.30
29
29
 
30
- > :warning: **BETA Software**: Working on being production-ready soon.
31
-
32
30
  # django-qstash
33
31
 
34
- _django-qstash_ is a drop-in replacement for Celery's `shared_task`.
32
+ Run background tasks with Django through webhooks and Upstash QStash.
33
+
34
+ _django-qstash_ is designed to be a drop-in replacement for Celery's `shared_task` or run alongside Celery.
35
35
 
36
36
 
37
37
  ## How it works
@@ -46,7 +46,7 @@ from django_qstash import shared_task
46
46
  def my_task():
47
47
  pass
48
48
  ```
49
- > To use Celery too, you can use `@stashed_task` instead of `@shared_task` more below.
49
+ > To use django-qstash with Celery, you can use `@stashed_task` instead of `@shared_task` (more below).
50
50
 
51
51
  To do this we need:
52
52
 
@@ -86,7 +86,9 @@ This allows us to:
86
86
  - [Arguments Must be JSON-ready](#arguments-must-be-json-ready)
87
87
  - [Example Task](#example-task)
88
88
  - [Management Commands](#management-commands)
89
- - [Public Domain In Development](#public-domain-in-development)
89
+ - [Development](#development)
90
+ - [Development with a Public Domain](#development-with-a-public-domain)
91
+ - [Development with Docker Compose](#development-with-docker-compose)
90
92
  - [Django Settings Configuration](#django-settings-configuration)
91
93
  - [`DJANGO_QSTASH_DOMAIN`](#django_qstash_domain)
92
94
  - [`DJANGO_QSTASH_WEBHOOK_PATH`](#django_qstash_webhook_path)
@@ -319,15 +321,33 @@ _Requires `django_qstash.schedules` installed._
319
321
  - `python manage.py task_schedules --list` see all schedules relate to the `DJANGO_QSTASH_DOMAIN`
320
322
  - `python manage.py task_schedules --sync` sync schedules based on the `DJANGO_QSTASH_DOMAIN` to store in the Django Admin.
321
323
 
322
- ## Public Domain In Development
324
+ ## Development
325
+
326
+ During development, you have two options:
327
+
328
+ - Use Upstash.com with a publicly accessible domain (preferred)
329
+ - Use Docker Compose with [compose.dev.yaml](./compose.dev.yaml)
330
+
331
+ ### Development with a Public Domain
332
+
333
+ The closer your development environment is to production the better. For that reason, using a publicly accessible domain is the preferred with to develop with _django-qstash_.
323
334
 
324
- django-qstash _requires_ a publicly accessible domain to work (e.g. `https://djangoqstash.com`). There are many ways to do this, we recommend:
335
+ To get a public domain during development, we recommend any of the following:
325
336
 
326
337
  - [Cloudflare Tunnels](https://developers.cloudflare.com/cloudflare-one/connections/connect-networks/) with a domain name you control.
327
338
  - [ngrok](https://ngrok.com/)
328
339
 
329
340
  Once you have a domain name, you can configure the `DJANGO_QSTASH_DOMAIN` setting in your Django settings.
330
341
 
342
+ ### Development with Docker Compose
343
+ Upstash covers how to run QStash during development on [this guide](https://upstash.com/docs/qstash/howto/local-development)
344
+
345
+ In our case we need to the following things:
346
+
347
+ - `docker compose -f compose.dev.yaml up`
348
+ - Add `QSTASH_URL=http://127.0.0.1:8585` to your `.env` file.
349
+ - Use the `QSTASH_TOKEN`, `QSTASH_CURRENT_SIGNING_KEY`, and `QSTASH_NEXT_SIGNING_KEY` the terminal output of Docker compose _or_ the values listed in [compose.dev.yaml](./compose.dev.yaml).
350
+
331
351
  ## Django Settings Configuration
332
352
 
333
353
  Various options are available to configure django-qstash.
@@ -371,10 +391,13 @@ CSRF_TRUSTED_ORIGINS = [os.environ.get("CSRF_TRUSTED_ORIGIN")]
371
391
  ###########################
372
392
  # qstash-py settings
373
393
  ###########################
394
+ USE_LOCAL_QSTASH = str(os.environ.get("USE_LOCAL_QSTASH")) == "1"
374
395
  QSTASH_TOKEN = os.environ.get("QSTASH_TOKEN")
375
396
  QSTASH_CURRENT_SIGNING_KEY = os.environ.get("QSTASH_CURRENT_SIGNING_KEY")
376
397
  QSTASH_NEXT_SIGNING_KEY = os.environ.get("QSTASH_NEXT_SIGNING_KEY")
377
-
398
+ if DJANGO_DEBUG and USE_LOCAL_QSTASH:
399
+ # connect to the docker compose qstash instance
400
+ os.environ["QSTASH_URL"] = "http://127.0.0.1:8585"
378
401
  ###########################
379
402
  # django_qstash settings
380
403
  ###########################
@@ -511,7 +534,7 @@ I think serverless is the answer. Pay for what you use and scale to zero when yo
511
534
 
512
535
  Django can be serverless and is pretty easy to do thanks to Docker and the countless hosting options and services out there. Celery cannot be serverless, at least yet.
513
536
 
514
- Let's face it. Celery is a powerful tool to run async background tasks but it comes at a cost. It needs at least one server running 24/7. For best performance it needs 2 (one worker, one beat). It also needs Redis or RabbitMQ. Most background processes that are tied to web apps are not serverless; they have to "listen" for their next task.
537
+ Let's face it. Celery is a powerful tool to run async background tasks but it comes at a cost. It needs at least one server running 24/7. For best performance, it needs 2 (one worker, one beat). It also needs Redis or RabbitMQ. In a traditional Django setup with Celery and Redis, you need to run 3 to 4 different processes. Most background processes that are tied to web apps are not serverless; they have to "listen" for their next task.
515
538
 
516
539
  To make Django truly scale-to-zero and serverless, we need to drop Celery.
517
540
 
@@ -525,4 +548,6 @@ It works by leveraging Upstash QStash to deliver messages about your tasks (e.g.
525
548
  >
526
549
  > Instead of calling an endpoint directly, QStash acts as a middleman between you and an API to guarantee delivery, perform automatic retries on failure, and more.
527
550
 
551
+ Compared to a traditional setup with Django, Celery, and Redis, which requires 3 to 4 processes, you only need to run a single process and can delegate the rest to Upstash QStash, significantly simplifying your infrastructure.
552
+
528
553
  django-qstash has a webhook handler that converts a QStash message to run a specific `@shared_task` function (the one that called `.delay()` or `.apply_async()`). It's easy, it's cheap, it's effective, and best of all, it unlocks the scale-to-zero potential of Django as a serverless app.
@@ -1,10 +1,10 @@
1
- django_qstash/__init__.py,sha256=X2HLkTrz3IPvofXBeKHkAqkJR823w9SRbbhs8kjVL9A,188
1
+ django_qstash/__init__.py,sha256=CgcGg1NNYz4b34ZlFtkp9A57qyWPBIamm6m3PNRObmE,187
2
2
  django_qstash/callbacks.py,sha256=IQ-D8sPlSRuREZ1zwkRyd2GtxfmrJJh2x4jLd39rZCE,813
3
- django_qstash/client.py,sha256=cgHf-g6lDAltY_Vt6GUVJNY2JSz1czBOHL-WVkkLs2M,149
3
+ django_qstash/client.py,sha256=9xO4iwR62PkEQhzC92yKRlzqEIF5Yi0HpYc88v_drsI,612
4
4
  django_qstash/cron.py,sha256=13OzTMGXFgjNEXjs2Et20WGZYtW9lKlu79BjbRySnVc,716
5
5
  django_qstash/exceptions.py,sha256=pH6kKRJFIVFkDHUJQ9yRWmtGdBBSXpNAwMSFuNzMgPw,392
6
6
  django_qstash/handlers.py,sha256=TtYZ-Sr858ajISBpDuHIT7-qaVsoVfTE6vVFJ9-kpPE,5820
7
- django_qstash/settings.py,sha256=YvpXMo1AdIWvbotISWJmhg0vrW3A3UQ4BieNzMfRC7Y,524
7
+ django_qstash/settings.py,sha256=s5xn4Rim8ip98q5Jiy1O6VVva2mUuAwUjbjo18fjqKA,579
8
8
  django_qstash/urls.py,sha256=1dNblYOCIBdqSXbA1jSL9H0aiXN5gIDVwhfZeC4-DQw,172
9
9
  django_qstash/utils.py,sha256=wrTU30cobO2di18BNEFtKD4ih2euf7eQNpg6p6TkQ1Y,1185
10
10
  django_qstash/views.py,sha256=H32f_jGnlwOTO0YG9znNo2b-GRYZ8TM-Wt0T62SGdXM,639
@@ -46,7 +46,7 @@ django_qstash/schedules/migrations/0001_initial.py,sha256=66cA8xnJV3h7QgzCaOiv-N
46
46
  django_qstash/schedules/migrations/0002_taskschedule_updated_at.py,sha256=6hZO0a9P2ZpOROkk7O5UXBhahghU0QfxZl4E-c3HKGw,459
47
47
  django_qstash/schedules/migrations/0003_alter_taskschedule_cron.py,sha256=oBW_FcvosKsa0l_l3eVDRIZli5K1wQaN_DJjamVe23s,826
48
48
  django_qstash/schedules/migrations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
49
- django_qstash-0.0.14.dist-info/METADATA,sha256=IwrF28uwoTMPK18baWNm_-T_8bHMB9GyHV-QFMgC-fE,19748
50
- django_qstash-0.0.14.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
51
- django_qstash-0.0.14.dist-info/top_level.txt,sha256=AlV3WSK1A0ZvKuCLsINtIJhJW8zo7SEB-D3_RAjZ0hI,14
52
- django_qstash-0.0.14.dist-info/RECORD,,
49
+ django_qstash-0.1.0.dist-info/METADATA,sha256=CJN-yK9a_FTT4HMR9BOlEJRuHZIUYQYEiVeKUnOmFJA,21263
50
+ django_qstash-0.1.0.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
51
+ django_qstash-0.1.0.dist-info/top_level.txt,sha256=AlV3WSK1A0ZvKuCLsINtIJhJW8zo7SEB-D3_RAjZ0hI,14
52
+ django_qstash-0.1.0.dist-info/RECORD,,