Skip to main content
Glama

Django Styleguide MCP Server

by dmmeteo
the-basics.md•3 kB
### The basics We try to treat Celery as if it's just another interface to our core logic - meaning - **don't put business logic there.** Lets look at an example of a **service** that sends emails (example taken from [`Django-Styleguide-Example`](https://github.com/HackSoftware/Django-Styleguide-Example/blob/master/styleguide_example/emails/tasks.py)) ```python from django.db import transaction from django.core.mail import EmailMultiAlternatives from styleguide_example.core.exceptions import ApplicationError from styleguide_example.common.services import model_update from styleguide_example.emails.models import Email @transaction.atomic def email_send(email: Email) -> Email: if email.status != Email.Status.SENDING: raise ApplicationError(f"Cannot send non-ready emails. Current status is {email.status}") subject = email.subject from_email = "styleguide-example@hacksoft.io" to = email.to html = email.html plain_text = email.plain_text msg = EmailMultiAlternatives(subject, plain_text, from_email, [to]) msg.attach_alternative(html, "text/html") msg.send() email, _ = model_update( instance=email, fields=["status", "sent_at"], data={ "status": Email.Status.SENT, "sent_at": timezone.now() } ) return email ``` Email sending has business logic around it, **but we still want to trigger this particular service from a task.** Our task looks like that: ```python from celery import shared_task from styleguide_example.emails.models import Email @shared_task def email_send(email_id): email = Email.objects.get(id=email_id) from styleguide_example.emails.services import email_send email_send(email) ``` As you can see, **we treat the task as an API:** 1. Fetch the required data. 2. Call the appropriate service. Now, imagine we have a different service, that triggers the email sending. It may look like that: ```python from django.db import transaction # ... more imports here ... from styleguide_example.emails.tasks import email_send as email_send_task @transaction.atomic def user_complete_onboarding(user: User) -> User: # ... some code here email = email_get_onboarding_template(user=user) transaction.on_commit(lambda: email_send_task.delay(email.id)) return user ``` 2 important things to point out here: 1. We are importing the task (which has the same name as the service), but we are giving it a `_task` suffix. 1. And when the transaction commits, we'll call the task. **So, in general, the way we use Celery can be described as:** 1. Tasks call services. 2. We import the service in the function body of the task. 3. When we want to trigger a task, we import the task, at module level, giving the `_task` suffix. 4. We execute tasks, as a side effect, whenever our transaction commits. This way of mixing tasks & services also **prevents circular imports**, which may occurr often enough when using Celery.

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/dmmeteo/django-styleguide-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server