django-database-task 0.2.0__tar.gz → 0.2.1__tar.gz

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.
Files changed (37) hide show
  1. {django_database_task-0.2.0/django_database_task.egg-info → django_database_task-0.2.1}/PKG-INFO +64 -17
  2. {django_database_task-0.2.0 → django_database_task-0.2.1}/README.md +63 -16
  3. {django_database_task-0.2.0 → django_database_task-0.2.1}/django_database_task/__init__.py +1 -1
  4. {django_database_task-0.2.0 → django_database_task-0.2.1}/django_database_task/backends.py +10 -6
  5. {django_database_task-0.2.0 → django_database_task-0.2.1}/django_database_task/cloudtasks/backend.py +14 -10
  6. {django_database_task-0.2.0 → django_database_task-0.2.1}/django_database_task/cloudtasks/detection.py +42 -5
  7. {django_database_task-0.2.0 → django_database_task-0.2.1/django_database_task.egg-info}/PKG-INFO +64 -17
  8. {django_database_task-0.2.0 → django_database_task-0.2.1}/pyproject.toml +1 -1
  9. {django_database_task-0.2.0 → django_database_task-0.2.1}/LICENSE +0 -0
  10. {django_database_task-0.2.0 → django_database_task-0.2.1}/MANIFEST.in +0 -0
  11. {django_database_task-0.2.0 → django_database_task-0.2.1}/django_database_task/admin.py +0 -0
  12. {django_database_task-0.2.0 → django_database_task-0.2.1}/django_database_task/apps.py +0 -0
  13. {django_database_task-0.2.0 → django_database_task-0.2.1}/django_database_task/cloudtasks/__init__.py +0 -0
  14. {django_database_task-0.2.0 → django_database_task-0.2.1}/django_database_task/cloudtasks/auth.py +0 -0
  15. {django_database_task-0.2.0 → django_database_task-0.2.1}/django_database_task/executor.py +0 -0
  16. {django_database_task-0.2.0 → django_database_task-0.2.1}/django_database_task/locale/ja/LC_MESSAGES/django.mo +0 -0
  17. {django_database_task-0.2.0 → django_database_task-0.2.1}/django_database_task/locale/ja/LC_MESSAGES/django.po +0 -0
  18. {django_database_task-0.2.0 → django_database_task-0.2.1}/django_database_task/management/__init__.py +0 -0
  19. {django_database_task-0.2.0 → django_database_task-0.2.1}/django_database_task/management/commands/__init__.py +0 -0
  20. {django_database_task-0.2.0 → django_database_task-0.2.1}/django_database_task/management/commands/purge_completed_database_tasks.py +0 -0
  21. {django_database_task-0.2.0 → django_database_task-0.2.1}/django_database_task/management/commands/run_database_tasks.py +0 -0
  22. {django_database_task-0.2.0 → django_database_task-0.2.1}/django_database_task/migrations/0001_initial.py +0 -0
  23. {django_database_task-0.2.0 → django_database_task-0.2.1}/django_database_task/migrations/__init__.py +0 -0
  24. {django_database_task-0.2.0 → django_database_task-0.2.1}/django_database_task/models.py +0 -0
  25. {django_database_task-0.2.0 → django_database_task-0.2.1}/django_database_task/urls.py +0 -0
  26. {django_database_task-0.2.0 → django_database_task-0.2.1}/django_database_task/views.py +0 -0
  27. {django_database_task-0.2.0 → django_database_task-0.2.1}/django_database_task.egg-info/SOURCES.txt +0 -0
  28. {django_database_task-0.2.0 → django_database_task-0.2.1}/django_database_task.egg-info/dependency_links.txt +0 -0
  29. {django_database_task-0.2.0 → django_database_task-0.2.1}/django_database_task.egg-info/requires.txt +0 -0
  30. {django_database_task-0.2.0 → django_database_task-0.2.1}/django_database_task.egg-info/top_level.txt +0 -0
  31. {django_database_task-0.2.0 → django_database_task-0.2.1}/setup.cfg +0 -0
  32. {django_database_task-0.2.0 → django_database_task-0.2.1}/tests/test_admin.py +0 -0
  33. {django_database_task-0.2.0 → django_database_task-0.2.1}/tests/test_backend.py +0 -0
  34. {django_database_task-0.2.0 → django_database_task-0.2.1}/tests/test_commands.py +0 -0
  35. {django_database_task-0.2.0 → django_database_task-0.2.1}/tests/test_executor.py +0 -0
  36. {django_database_task-0.2.0 → django_database_task-0.2.1}/tests/test_models.py +0 -0
  37. {django_database_task-0.2.0 → django_database_task-0.2.1}/tests/test_views.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: django-database-task
3
- Version: 0.2.0
3
+ Version: 0.2.1
4
4
  Summary: A database-backed task queue backend for Django 6.0's built-in task framework
5
5
  Author-email: Shinya Okano <tokibito@gmail.com>
6
6
  Maintainer-email: Shinya Okano <tokibito@gmail.com>
@@ -607,21 +607,68 @@ pip install django-database-task[cloudtasks]
607
607
  TASKS = {
608
608
  "default": {
609
609
  "BACKEND": "django_database_task.cloudtasks.CloudTasksDatabaseBackend",
610
- "OPTIONS": {
611
- "CLOUD_TASKS_QUEUE": "default", # Only required setting
612
- },
610
+ "QUEUES": [], # Allow all queue names
613
611
  },
614
612
  }
615
613
  ```
616
614
 
617
- Project ID, location, and handler URL are auto-detected from GAE/Cloud Run environment variables.
615
+ Project ID, location, and handler URL are auto-detected from GAE/Cloud Run environment.
618
616
 
619
- ### How It Works
617
+ **Important**: Set `QUEUES: []` to allow any queue name, or list the queues you use:
618
+ ```python
619
+ "QUEUES": ["default", "emails", "batch"], # Only these queues allowed
620
+ ```
621
+
622
+ The Cloud Tasks queue name is determined by the task's `queue_name` attribute:
620
623
 
624
+ ```python
625
+ @task # Uses "default" queue
626
+ def normal_task():
627
+ pass
628
+
629
+ @task(queue="batch") # Uses "batch" queue
630
+ def batch_task():
631
+ pass
632
+
633
+ @task(queue="high-priority") # Uses "high-priority" queue
634
+ def urgent_task():
635
+ pass
621
636
  ```
622
- 1. App enqueues task → Task saved to database + Cloud Task created
623
- 2. Cloud Task triggers HTTP request /tasks/execute/<task_id>/
624
- 3. Handler retrieves task from database and executes it
637
+
638
+ This allows you to configure different rate limits and concurrency settings per queue in Cloud Tasks.
639
+
640
+ ### How It Works
641
+
642
+ ```mermaid
643
+ sequenceDiagram
644
+ participant App as Application
645
+ participant Backend as CloudTasksDatabaseBackend
646
+ participant DB as Database
647
+ participant CT as Cloud Tasks
648
+ participant Handler as /tasks/execute/
649
+
650
+ Note over App,Handler: Task Enqueue
651
+ App->>Backend: task.enqueue(args, kwargs)
652
+ Backend->>DB: INSERT task (status=READY)
653
+ DB-->>Backend: Task ID
654
+ Backend->>CT: Create Cloud Task (task_id only)
655
+ CT-->>Backend: OK
656
+ Backend-->>App: TaskResult (id, status=READY)
657
+
658
+ Note over App,Handler: Task Execution (triggered by Cloud Tasks)
659
+ CT->>Handler: POST /tasks/execute/<task_id>/<br/>(with OIDC token if configured)
660
+ Handler->>Handler: Verify OIDC token (optional)
661
+ Handler->>DB: SELECT task by ID
662
+ DB-->>Handler: Task record
663
+ Handler->>DB: UPDATE status=RUNNING
664
+ Handler->>Handler: Execute task function
665
+ alt Success
666
+ Handler->>DB: UPDATE status=SUCCESSFUL
667
+ Handler-->>CT: HTTP 200
668
+ else Failure
669
+ Handler->>DB: UPDATE status=FAILED
670
+ Handler-->>CT: HTTP 500 (triggers retry)
671
+ end
625
672
  ```
626
673
 
627
674
  The Cloud Task only contains the task ID. All task parameters are stored in the database, ensuring:
@@ -636,10 +683,9 @@ TASKS = {
636
683
  "default": {
637
684
  "BACKEND": "django_database_task.cloudtasks.CloudTasksDatabaseBackend",
638
685
  "OPTIONS": {
639
- # Required
640
- "CLOUD_TASKS_QUEUE": "default",
686
+ # All settings are optional - auto-detected from environment
641
687
 
642
- # Auto-detected (override if needed)
688
+ # Override auto-detection if needed
643
689
  # "CLOUD_TASKS_PROJECT": "my-project",
644
690
  # "CLOUD_TASKS_LOCATION": "asia-northeast1",
645
691
  # "TASK_HANDLER_URL": "https://myapp.example.com/tasks/execute/{task_id}/",
@@ -655,11 +701,12 @@ TASKS = {
655
701
 
656
702
  ### Auto-Detection
657
703
 
658
- | Setting | Environment Variable | Description |
659
- |---------|---------------------|-------------|
660
- | Project | `GOOGLE_CLOUD_PROJECT` | GCP project ID |
661
- | Location | `CLOUD_RUN_REGION` / `GAE_REGION` | Cloud Tasks region |
704
+ | Setting | Detection Method | Description |
705
+ |---------|------------------|-------------|
706
+ | Project | `GOOGLE_CLOUD_PROJECT` env var | GCP project ID |
707
+ | Location | `CLOUD_RUN_REGION` env var, or metadata server | Cloud Tasks region |
662
708
  | Handler URL | Built from `K_SERVICE`, `GAE_SERVICE`, `GAE_VERSION` | Task execution endpoint |
709
+ | Queue name | Task's `queue_name` attribute | Defaults to "default" |
663
710
 
664
711
  ### OIDC Authentication
665
712
 
@@ -670,8 +717,8 @@ When `OIDC_SERVICE_ACCOUNT_EMAIL` is configured, Cloud Tasks will send OIDC toke
670
717
  TASKS = {
671
718
  "default": {
672
719
  "BACKEND": "django_database_task.cloudtasks.CloudTasksDatabaseBackend",
720
+ "QUEUES": [], # Allow all queue names
673
721
  "OPTIONS": {
674
- "CLOUD_TASKS_QUEUE": "default",
675
722
  "OIDC_SERVICE_ACCOUNT_EMAIL": "my-sa@project.iam.gserviceaccount.com",
676
723
  # OIDC_AUDIENCE is auto-detected from handler URL if not set
677
724
  },
@@ -571,21 +571,68 @@ pip install django-database-task[cloudtasks]
571
571
  TASKS = {
572
572
  "default": {
573
573
  "BACKEND": "django_database_task.cloudtasks.CloudTasksDatabaseBackend",
574
- "OPTIONS": {
575
- "CLOUD_TASKS_QUEUE": "default", # Only required setting
576
- },
574
+ "QUEUES": [], # Allow all queue names
577
575
  },
578
576
  }
579
577
  ```
580
578
 
581
- Project ID, location, and handler URL are auto-detected from GAE/Cloud Run environment variables.
579
+ Project ID, location, and handler URL are auto-detected from GAE/Cloud Run environment.
582
580
 
583
- ### How It Works
581
+ **Important**: Set `QUEUES: []` to allow any queue name, or list the queues you use:
582
+ ```python
583
+ "QUEUES": ["default", "emails", "batch"], # Only these queues allowed
584
+ ```
585
+
586
+ The Cloud Tasks queue name is determined by the task's `queue_name` attribute:
584
587
 
588
+ ```python
589
+ @task # Uses "default" queue
590
+ def normal_task():
591
+ pass
592
+
593
+ @task(queue="batch") # Uses "batch" queue
594
+ def batch_task():
595
+ pass
596
+
597
+ @task(queue="high-priority") # Uses "high-priority" queue
598
+ def urgent_task():
599
+ pass
585
600
  ```
586
- 1. App enqueues task → Task saved to database + Cloud Task created
587
- 2. Cloud Task triggers HTTP request /tasks/execute/<task_id>/
588
- 3. Handler retrieves task from database and executes it
601
+
602
+ This allows you to configure different rate limits and concurrency settings per queue in Cloud Tasks.
603
+
604
+ ### How It Works
605
+
606
+ ```mermaid
607
+ sequenceDiagram
608
+ participant App as Application
609
+ participant Backend as CloudTasksDatabaseBackend
610
+ participant DB as Database
611
+ participant CT as Cloud Tasks
612
+ participant Handler as /tasks/execute/
613
+
614
+ Note over App,Handler: Task Enqueue
615
+ App->>Backend: task.enqueue(args, kwargs)
616
+ Backend->>DB: INSERT task (status=READY)
617
+ DB-->>Backend: Task ID
618
+ Backend->>CT: Create Cloud Task (task_id only)
619
+ CT-->>Backend: OK
620
+ Backend-->>App: TaskResult (id, status=READY)
621
+
622
+ Note over App,Handler: Task Execution (triggered by Cloud Tasks)
623
+ CT->>Handler: POST /tasks/execute/<task_id>/<br/>(with OIDC token if configured)
624
+ Handler->>Handler: Verify OIDC token (optional)
625
+ Handler->>DB: SELECT task by ID
626
+ DB-->>Handler: Task record
627
+ Handler->>DB: UPDATE status=RUNNING
628
+ Handler->>Handler: Execute task function
629
+ alt Success
630
+ Handler->>DB: UPDATE status=SUCCESSFUL
631
+ Handler-->>CT: HTTP 200
632
+ else Failure
633
+ Handler->>DB: UPDATE status=FAILED
634
+ Handler-->>CT: HTTP 500 (triggers retry)
635
+ end
589
636
  ```
590
637
 
591
638
  The Cloud Task only contains the task ID. All task parameters are stored in the database, ensuring:
@@ -600,10 +647,9 @@ TASKS = {
600
647
  "default": {
601
648
  "BACKEND": "django_database_task.cloudtasks.CloudTasksDatabaseBackend",
602
649
  "OPTIONS": {
603
- # Required
604
- "CLOUD_TASKS_QUEUE": "default",
650
+ # All settings are optional - auto-detected from environment
605
651
 
606
- # Auto-detected (override if needed)
652
+ # Override auto-detection if needed
607
653
  # "CLOUD_TASKS_PROJECT": "my-project",
608
654
  # "CLOUD_TASKS_LOCATION": "asia-northeast1",
609
655
  # "TASK_HANDLER_URL": "https://myapp.example.com/tasks/execute/{task_id}/",
@@ -619,11 +665,12 @@ TASKS = {
619
665
 
620
666
  ### Auto-Detection
621
667
 
622
- | Setting | Environment Variable | Description |
623
- |---------|---------------------|-------------|
624
- | Project | `GOOGLE_CLOUD_PROJECT` | GCP project ID |
625
- | Location | `CLOUD_RUN_REGION` / `GAE_REGION` | Cloud Tasks region |
668
+ | Setting | Detection Method | Description |
669
+ |---------|------------------|-------------|
670
+ | Project | `GOOGLE_CLOUD_PROJECT` env var | GCP project ID |
671
+ | Location | `CLOUD_RUN_REGION` env var, or metadata server | Cloud Tasks region |
626
672
  | Handler URL | Built from `K_SERVICE`, `GAE_SERVICE`, `GAE_VERSION` | Task execution endpoint |
673
+ | Queue name | Task's `queue_name` attribute | Defaults to "default" |
627
674
 
628
675
  ### OIDC Authentication
629
676
 
@@ -634,8 +681,8 @@ When `OIDC_SERVICE_ACCOUNT_EMAIL` is configured, Cloud Tasks will send OIDC toke
634
681
  TASKS = {
635
682
  "default": {
636
683
  "BACKEND": "django_database_task.cloudtasks.CloudTasksDatabaseBackend",
684
+ "QUEUES": [], # Allow all queue names
637
685
  "OPTIONS": {
638
- "CLOUD_TASKS_QUEUE": "default",
639
686
  "OIDC_SERVICE_ACCOUNT_EMAIL": "my-sa@project.iam.gserviceaccount.com",
640
687
  # OIDC_AUDIENCE is auto-detected from handler URL if not set
641
688
  },
@@ -2,7 +2,7 @@
2
2
  django-database-task: A database-backed task queue backend for Django 6.0's task framework.
3
3
  """
4
4
 
5
- __version__ = "0.2.0"
5
+ __version__ = "0.2.1"
6
6
 
7
7
 
8
8
  def __getattr__(name):
@@ -169,15 +169,19 @@ class DatabaseTaskBackend(BaseTaskBackend):
169
169
  args = db_task.args_json
170
170
  kwargs = db_task.kwargs_json.copy()
171
171
 
172
+ # Execute task
173
+ # If takes_context, pass TaskContext as first positional argument
172
174
  if takes_context:
173
175
  context = TaskContext(task_result=task_result)
174
- kwargs["context"] = context
175
-
176
- # Execute task
177
- if iscoroutinefunction(func):
178
- return_value = asyncio.run(func(*args, **kwargs))
176
+ if iscoroutinefunction(func):
177
+ return_value = asyncio.run(func(context, *args, **kwargs))
178
+ else:
179
+ return_value = func(context, *args, **kwargs)
179
180
  else:
180
- return_value = func(*args, **kwargs)
181
+ if iscoroutinefunction(func):
182
+ return_value = asyncio.run(func(*args, **kwargs))
183
+ else:
184
+ return_value = func(*args, **kwargs)
181
185
 
182
186
  # Normalize return value for JSON serialization
183
187
  # This will raise TypeError for unsupported types
@@ -37,11 +37,17 @@ class CloudTasksDatabaseBackend(DatabaseTaskBackend):
37
37
  TASKS = {
38
38
  "default": {
39
39
  "BACKEND": "django_database_task.cloudtasks.CloudTasksDatabaseBackend",
40
- "OPTIONS": {
41
- "CLOUD_TASKS_QUEUE": "default",
42
- },
43
40
  },
44
41
  }
42
+
43
+ The Cloud Tasks queue name is determined by the task's queue_name attribute.
44
+ For example:
45
+ @task(queue="high-priority")
46
+ def urgent_task():
47
+ ...
48
+ will use the "high-priority" Cloud Tasks queue.
49
+
50
+ Tasks without explicit queue use Django's DEFAULT_TASK_QUEUE_NAME ("default").
45
51
  """
46
52
 
47
53
  def __init__(self, alias, params):
@@ -49,11 +55,6 @@ class CloudTasksDatabaseBackend(DatabaseTaskBackend):
49
55
 
50
56
  options = params.get("OPTIONS", {})
51
57
 
52
- # Required: Queue name
53
- self.queue_name = options.get("CLOUD_TASKS_QUEUE")
54
- if not self.queue_name:
55
- raise ImproperlyConfigured("CLOUD_TASKS_QUEUE is required in TASKS OPTIONS")
56
-
57
58
  # Auto-detected or explicit: Project ID
58
59
  self.project = options.get("CLOUD_TASKS_PROJECT") or detect_gcp_project()
59
60
  if not self.project:
@@ -188,12 +189,15 @@ class CloudTasksDatabaseBackend(DatabaseTaskBackend):
188
189
 
189
190
  The Cloud Task only contains the task ID in the URL.
190
191
  Task parameters are retrieved from the database when executed.
192
+
193
+ The Cloud Tasks queue name is taken from the task's queue_name attribute.
191
194
  """
192
- # Build queue path
195
+ # Build queue path using task's queue_name
196
+ queue_name = task_result.task.queue_name
193
197
  parent = self.client.queue_path(
194
198
  self.project,
195
199
  self.location,
196
- self.queue_name,
200
+ queue_name,
197
201
  )
198
202
 
199
203
  # Build task handler URL (contains only task ID)
@@ -31,7 +31,7 @@ def detect_gcp_project():
31
31
 
32
32
  def detect_gcp_location():
33
33
  """
34
- Detect Cloud Tasks location (region) from environment variables.
34
+ Detect Cloud Tasks location (region) from environment variables or metadata server.
35
35
 
36
36
  Returns:
37
37
  Region string or None if not detected.
@@ -41,16 +41,53 @@ def detect_gcp_location():
41
41
  if region:
42
42
  return region
43
43
 
44
- # GAE: Check for region environment variables
45
- region = os.environ.get("GAE_REGION") or os.environ.get("GOOGLE_CLOUD_REGION")
44
+ # Explicit environment variable (works for any environment)
45
+ region = os.environ.get("GOOGLE_CLOUD_REGION")
46
+ if region:
47
+ return region
48
+
49
+ # GAE/GCE: Query metadata server for zone and extract region
50
+ region = _detect_region_from_metadata()
46
51
  if region:
47
52
  return region
48
53
 
49
- # Note: GAE may not provide region via environment variables
50
- # In that case, explicit configuration is required
51
54
  return None
52
55
 
53
56
 
57
+ def _detect_region_from_metadata():
58
+ """
59
+ Detect region from GCP metadata server.
60
+
61
+ The metadata server returns zone in format:
62
+ projects/PROJECT_NUMBER/zones/ZONE_NAME (e.g., projects/12345/zones/us-central1-a)
63
+
64
+ We extract the region by removing the zone suffix (e.g., us-central1).
65
+
66
+ Returns:
67
+ Region string or None if not available.
68
+ """
69
+ import urllib.request
70
+ import urllib.error
71
+
72
+ metadata_url = "http://metadata.google.internal/computeMetadata/v1/instance/zone"
73
+ headers = {"Metadata-Flavor": "Google"}
74
+
75
+ try:
76
+ request = urllib.request.Request(metadata_url, headers=headers)
77
+ with urllib.request.urlopen(request, timeout=2) as response:
78
+ # Response format: projects/PROJECT_NUMBER/zones/ZONE_NAME
79
+ zone_path = response.read().decode("utf-8")
80
+ # Extract zone name (last part)
81
+ zone = zone_path.split("/")[-1]
82
+ # Extract region by removing the last part (e.g., us-central1-a -> us-central1)
83
+ # Zone format: {region}-{zone_letter} (e.g., us-central1-a, asia-northeast1-b)
84
+ region = "-".join(zone.rsplit("-", 1)[:-1])
85
+ return region if region else None
86
+ except (urllib.error.URLError, OSError):
87
+ # Metadata server not available (local development, etc.)
88
+ return None
89
+
90
+
54
91
  def detect_default_service_account():
55
92
  """
56
93
  Detect the default service account email.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: django-database-task
3
- Version: 0.2.0
3
+ Version: 0.2.1
4
4
  Summary: A database-backed task queue backend for Django 6.0's built-in task framework
5
5
  Author-email: Shinya Okano <tokibito@gmail.com>
6
6
  Maintainer-email: Shinya Okano <tokibito@gmail.com>
@@ -607,21 +607,68 @@ pip install django-database-task[cloudtasks]
607
607
  TASKS = {
608
608
  "default": {
609
609
  "BACKEND": "django_database_task.cloudtasks.CloudTasksDatabaseBackend",
610
- "OPTIONS": {
611
- "CLOUD_TASKS_QUEUE": "default", # Only required setting
612
- },
610
+ "QUEUES": [], # Allow all queue names
613
611
  },
614
612
  }
615
613
  ```
616
614
 
617
- Project ID, location, and handler URL are auto-detected from GAE/Cloud Run environment variables.
615
+ Project ID, location, and handler URL are auto-detected from GAE/Cloud Run environment.
618
616
 
619
- ### How It Works
617
+ **Important**: Set `QUEUES: []` to allow any queue name, or list the queues you use:
618
+ ```python
619
+ "QUEUES": ["default", "emails", "batch"], # Only these queues allowed
620
+ ```
621
+
622
+ The Cloud Tasks queue name is determined by the task's `queue_name` attribute:
620
623
 
624
+ ```python
625
+ @task # Uses "default" queue
626
+ def normal_task():
627
+ pass
628
+
629
+ @task(queue="batch") # Uses "batch" queue
630
+ def batch_task():
631
+ pass
632
+
633
+ @task(queue="high-priority") # Uses "high-priority" queue
634
+ def urgent_task():
635
+ pass
621
636
  ```
622
- 1. App enqueues task → Task saved to database + Cloud Task created
623
- 2. Cloud Task triggers HTTP request /tasks/execute/<task_id>/
624
- 3. Handler retrieves task from database and executes it
637
+
638
+ This allows you to configure different rate limits and concurrency settings per queue in Cloud Tasks.
639
+
640
+ ### How It Works
641
+
642
+ ```mermaid
643
+ sequenceDiagram
644
+ participant App as Application
645
+ participant Backend as CloudTasksDatabaseBackend
646
+ participant DB as Database
647
+ participant CT as Cloud Tasks
648
+ participant Handler as /tasks/execute/
649
+
650
+ Note over App,Handler: Task Enqueue
651
+ App->>Backend: task.enqueue(args, kwargs)
652
+ Backend->>DB: INSERT task (status=READY)
653
+ DB-->>Backend: Task ID
654
+ Backend->>CT: Create Cloud Task (task_id only)
655
+ CT-->>Backend: OK
656
+ Backend-->>App: TaskResult (id, status=READY)
657
+
658
+ Note over App,Handler: Task Execution (triggered by Cloud Tasks)
659
+ CT->>Handler: POST /tasks/execute/<task_id>/<br/>(with OIDC token if configured)
660
+ Handler->>Handler: Verify OIDC token (optional)
661
+ Handler->>DB: SELECT task by ID
662
+ DB-->>Handler: Task record
663
+ Handler->>DB: UPDATE status=RUNNING
664
+ Handler->>Handler: Execute task function
665
+ alt Success
666
+ Handler->>DB: UPDATE status=SUCCESSFUL
667
+ Handler-->>CT: HTTP 200
668
+ else Failure
669
+ Handler->>DB: UPDATE status=FAILED
670
+ Handler-->>CT: HTTP 500 (triggers retry)
671
+ end
625
672
  ```
626
673
 
627
674
  The Cloud Task only contains the task ID. All task parameters are stored in the database, ensuring:
@@ -636,10 +683,9 @@ TASKS = {
636
683
  "default": {
637
684
  "BACKEND": "django_database_task.cloudtasks.CloudTasksDatabaseBackend",
638
685
  "OPTIONS": {
639
- # Required
640
- "CLOUD_TASKS_QUEUE": "default",
686
+ # All settings are optional - auto-detected from environment
641
687
 
642
- # Auto-detected (override if needed)
688
+ # Override auto-detection if needed
643
689
  # "CLOUD_TASKS_PROJECT": "my-project",
644
690
  # "CLOUD_TASKS_LOCATION": "asia-northeast1",
645
691
  # "TASK_HANDLER_URL": "https://myapp.example.com/tasks/execute/{task_id}/",
@@ -655,11 +701,12 @@ TASKS = {
655
701
 
656
702
  ### Auto-Detection
657
703
 
658
- | Setting | Environment Variable | Description |
659
- |---------|---------------------|-------------|
660
- | Project | `GOOGLE_CLOUD_PROJECT` | GCP project ID |
661
- | Location | `CLOUD_RUN_REGION` / `GAE_REGION` | Cloud Tasks region |
704
+ | Setting | Detection Method | Description |
705
+ |---------|------------------|-------------|
706
+ | Project | `GOOGLE_CLOUD_PROJECT` env var | GCP project ID |
707
+ | Location | `CLOUD_RUN_REGION` env var, or metadata server | Cloud Tasks region |
662
708
  | Handler URL | Built from `K_SERVICE`, `GAE_SERVICE`, `GAE_VERSION` | Task execution endpoint |
709
+ | Queue name | Task's `queue_name` attribute | Defaults to "default" |
663
710
 
664
711
  ### OIDC Authentication
665
712
 
@@ -670,8 +717,8 @@ When `OIDC_SERVICE_ACCOUNT_EMAIL` is configured, Cloud Tasks will send OIDC toke
670
717
  TASKS = {
671
718
  "default": {
672
719
  "BACKEND": "django_database_task.cloudtasks.CloudTasksDatabaseBackend",
720
+ "QUEUES": [], # Allow all queue names
673
721
  "OPTIONS": {
674
- "CLOUD_TASKS_QUEUE": "default",
675
722
  "OIDC_SERVICE_ACCOUNT_EMAIL": "my-sa@project.iam.gserviceaccount.com",
676
723
  # OIDC_AUDIENCE is auto-detected from handler URL if not set
677
724
  },
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "django-database-task"
7
- version = "0.2.0"
7
+ version = "0.2.1"
8
8
  description = "A database-backed task queue backend for Django 6.0's built-in task framework"
9
9
  readme = "README.md"
10
10
  license = "MIT"