-
Notifications
You must be signed in to change notification settings - Fork 77
Add Django 6 compatibility and modernise codebase #105
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
274a737
8033d8c
d458d22
00fc485
fb7b0ae
3e91c69
53856cb
3fb0f83
afd917c
cd07284
4458807
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,4 +1,3 @@ | ||
| .vagrant | ||
| sandbox/db.sqlite3 | ||
| docs/_build | ||
| dist/* | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,3 +1,5 @@ | ||
| 3.8.5 | ||
| 3.7.8 | ||
| 3.6.11 | ||
| 3.10.19 | ||
| 3.11.14 | ||
| 3.12.12 | ||
| 3.13.11 | ||
| 3.14.2 |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -2,7 +2,7 @@ build: | |
| image: latest | ||
|
|
||
| python: | ||
| version: 3.8 | ||
| version: 3.10 | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Wouldn't it make sense to upgrade to 3.14 right away? |
||
| pip_install: true | ||
| extra_requirements: | ||
| - docs | ||
|
|
||
This file was deleted.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -6,7 +6,6 @@ | |
| from django.conf import settings | ||
| from django.core.cache import DEFAULT_CACHE_ALIAS, caches | ||
| from django.db.models import Model as DjangoModel | ||
| from django.utils.itercompat import is_iterable | ||
|
|
||
| from .utils import enqueue_task, get_job_class | ||
|
|
||
|
|
@@ -29,15 +28,15 @@ def to_bytestring(value): | |
| :returns: a bytestring | ||
| """ | ||
| if isinstance(value, DjangoModel): | ||
| return ('%s:%s' % (value.__class__, hash(value))).encode('utf-8') | ||
| return (f'{value.__class__}:{hash(value)}').encode('utf-8') | ||
| if isinstance(value, str): | ||
| return value.encode('utf8') | ||
| if isinstance(value, bytes): | ||
| return value | ||
| return bytes(str(value), 'utf8') | ||
|
|
||
|
|
||
| class Job(object): | ||
| class Job: | ||
| """ | ||
| A cached read job. | ||
|
|
||
|
|
@@ -59,7 +58,7 @@ class Job(object): | |
| #: refresh the cache. | ||
| refresh_timeout = 60 | ||
|
|
||
| #: Secifies which cache to use from your `CACHES` setting. It defaults to | ||
| #: Specifies which cache to use from your `CACHES` setting. It defaults to | ||
| #: `default`. | ||
| cache_alias = None | ||
|
|
||
|
|
@@ -91,7 +90,7 @@ class Job(object): | |
|
|
||
| @property | ||
| def class_path(self): | ||
| return '%s.%s' % (self.__module__, self.__class__.__name__) | ||
| return f'{self.__module__}.{self.__class__.__name__}' | ||
|
|
||
| def __init__(self): | ||
| self.cache_alias = self.cache_alias or getattr( | ||
|
|
@@ -283,6 +282,10 @@ def set(self, *raw_args, **raw_kwargs): | |
| # HELPER METHODS | ||
| # -------------- | ||
|
|
||
| @staticmethod | ||
| def is_iterable(value): | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. As we only use it once, I'd not have it as a separate method, especially not as a staticmethod :) |
||
| return isinstance(value, collections.abc.Iterable) | ||
|
|
||
| def prepare_args(self, *args): | ||
| return args | ||
|
|
||
|
|
@@ -399,11 +402,11 @@ def key(self, *args, **kwargs): | |
| return self.class_path | ||
| try: | ||
| if args and not kwargs: | ||
| return "%s:%s" % (self.class_path, self.hash(args)) | ||
| return f"{self.class_path}:{self.hash(args)}" | ||
| # The line might break if your passed values are un-hashable. If | ||
| # it does, you need to override this method and implement your own | ||
| # key algorithm. | ||
| return "%s:%s:%s:%s" % ( | ||
| return "{}:{}:{}:{}".format( | ||
| self.class_path, | ||
| self.hash(args), | ||
| self.hash([k for k in sorted(kwargs)]), | ||
|
|
@@ -422,7 +425,7 @@ def hash(self, value): | |
|
|
||
| This is for use in a cache key. | ||
| """ | ||
| if is_iterable(value): | ||
| if self.is_iterable(value): | ||
| value = tuple(to_bytestring(v) for v in value) | ||
| return hashlib.md5(b':'.join(value)).hexdigest() | ||
|
|
||
|
|
@@ -440,7 +443,7 @@ def process_result(self, result, call, cache_status, sync_fetch=None): | |
| :param result: The result to be returned | ||
| :param call: A named tuple with properties 'args' and 'kwargs that | ||
| holds the call args and kwargs | ||
| :param cache_status: A status integrer, accessible as class constants | ||
| :param cache_status: A status integer, accessible as class constants | ||
| self.MISS, self.HIT, self.STALE | ||
| :param sync_fetch: A boolean indicating whether a synchronous fetch was | ||
| performed. A value of None indicates that no fetch | ||
|
|
||
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
| @@ -0,0 +1,41 @@ | ||||||
| services: | ||||||
| django: &django | ||||||
| build: | ||||||
| context: . | ||||||
| dockerfile: sandbox/Dockerfile | ||||||
| entrypoint: /app/entrypoint | ||||||
| environment: | ||||||
| REDIS_HOST: redis | ||||||
| REDIS_PORT: 6379 | ||||||
| REDIS_DB: 0 | ||||||
| volumes: | ||||||
| - ./sandbox:/app | ||||||
| ports: | ||||||
| - "8080:8080" | ||||||
| depends_on: | ||||||
| redis: | ||||||
| condition: service_healthy | ||||||
|
|
||||||
| redis: | ||||||
| image: redis:7-alpine | ||||||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
| healthcheck: | ||||||
| test: ["CMD", "redis-cli", "ping"] | ||||||
| interval: 5s | ||||||
| timeout: 3s | ||||||
| retries: 10 | ||||||
|
|
||||||
| celery: | ||||||
| depends_on: | ||||||
| - django | ||||||
| - redis | ||||||
| <<: *django | ||||||
| ports: [] | ||||||
| entrypoint: celery -A sandbox worker --loglevel=INFO | ||||||
|
|
||||||
| rqworker: | ||||||
| depends_on: | ||||||
| - django | ||||||
| - redis | ||||||
| <<: *django | ||||||
| ports: [] | ||||||
| entrypoint: python manage.py rqworker | ||||||
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -38,24 +38,16 @@ all supported Django and Python versions:: | |||||
| Sandbox VM | ||||||
| ========== | ||||||
|
|
||||||
| There is a ``VagrantFile`` for setting up a sandbox VM where you can play around | ||||||
| with the functionality. Bring up the Vagrant box:: | ||||||
| Alternatively, there's a ``docker compose`` stack for setting up a sandbox | ||||||
| environment where you can play around with the functionality. | ||||||
| Bring up the compose stack:: | ||||||
|
|
||||||
| $ vagrant up | ||||||
| $ docker compose up | ||||||
|
|
||||||
| This may take a while but will set up a Ubuntu Precise64 VM with RabbitMQ | ||||||
| installed. You can then SSH into the machine:: | ||||||
| The stack will start with Celery as a broker by default. You can Alternatively | ||||||
| make use of rq by supplying the `Q` env var: | ||||||
|
|
||||||
| $ vagrant ssh | ||||||
| $ cd /vagrant/sandbox | ||||||
|
|
||||||
| You can now decide to run the Celery implementation:: | ||||||
|
|
||||||
| $ honcho -f Procfile.celery start | ||||||
|
|
||||||
| Or you can run the RQ implementation:: | ||||||
|
|
||||||
| $ honcho -f Procfile.rq start | ||||||
| $ Q=rq docker compose up | ||||||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
Lets make it more verbose. |
||||||
|
|
||||||
| The above commands will start a Django runserver and the selected task worker. | ||||||
| The dummy site will be available at ``http://localhost:8080`` on your host | ||||||
|
|
||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You cann add the extra install to the line above where we install poetry.