PulseHub is a Django 5 platform that combines a classic CRM for relationship management with a Memgraph‑backed knowledge graph, LLM‑assisted data entry, and chat interfaces. The UI copy is mainly German, but the stack is fully configurable through environment variables and Docker Compose.
- Contacts, organisations, industries, tags, and interaction tracking (
app/). - CSV/Outlook exports, Select2-based search, and historical auditing via
django-simple-history. - Business card ingestion that uses Ollama’s
llama3.2-visionmodel to prefill people and company forms (app/utils.py,app/views.py:347). - Knowledge-graph utilities (
pulsekg/) that map people, skills, projects, repositories, and publications into Memgraph. - Skill mining from publications/GitHub repos/subprojects via
ollama+ LangChain (pulsekg/skill_generator.py,pulsekg/views.py:63). - Read-only LangChain agent that chats over Memgraph with Cypher validation and vector search tooling (
pulsekg/ollama_memgraph.py,pulsekg/views.py:17). - Docker Compose stack with Gunicorn, Nginx, PostgreSQL+pgvector, optional legacy MySQL, and Memgraph.
- Django project (
pulsehub/) – settings, URL routing, and WSGI/ASGI entry points.LANGUAGE_CODEisde-DEand the default timezone isEurope/Berlin. - Apps
app/: CRM, authentication views, Select2 widgets/autocomplete, CSV exporters, and the business-card workflow.pulsekg/: Memgraph service layer, LangChain chat agent, dashboards for managing personal skills/projects/repos/pubs, and staff tools.
- Services – Docker builds a Gunicorn container fronted by Nginx (port
6001), PostgreSQL with pgvector, optional MySQL (used for legacy migrations), and Memgraph (with exposed Bolt/HTTP ports for local debugging). - LLM/AI components – Ollama provides local models for:
- Skill extraction (
gemma3:27bby default). - Embeddings (
embeddinggemma:latest). - Vision OCR for business cards (
llama3.2-vision).
- Skill extraction (
- Static/media –
STATIC_ROOTpoints tostaticfiles/,MEDIA_ROOTtomedia/. Docker volumes keep these persistent across deploys.
| Path | Role |
|---|---|
manage.py |
Django management entry point. |
pulsehub/ |
Project configuration (settings.py, urls.py, asgi.py, wsgi.py). |
app/ |
CRM models, forms, views, Select2 widgets, and templates (app/templates/). |
pulsekg/ |
Memgraph data models, LangChain agent (ollama_memgraph.py), skill generator, and dashboards. |
templates/ |
Project-wide templates (error pages, auth). |
export/ |
Static HTML prototypes kept as design references. |
media/ |
Upload bucket (business card images are temporarily stored here). |
docker-compose.yaml / docker-compose-test.yaml |
Production-like vs. local/test compose definitions. |
entrypoint.sh |
Container entry script running migrations, collecting static files, and then launching Gunicorn. |
nginx.conf |
Reverse proxy config served on port 6001. |
migration_guide.md |
Step-by-step instructions for migrating legacy MySQL data into PostgreSQL. |
requirements.txt |
Python dependencies (Django, LangChain, Memgraph clients, pgvector, etc.). |
- Python ≥ 3.12
- Node is not required; all UI is server-rendered.
- Docker + Docker Compose (v2) for containerised runs.
- Running instances (local or remote) of:
- PostgreSQL 15+ with pgvector extension (or use the provided Compose service).
- Memgraph (default Bolt port
7687). - Optional MySQL (only needed when following
migration_guide.md). - Ollama with the required models pulled beforehand.
Create two files in the repo root when using Docker:
.env.prod– consumed by the Django, PostgreSQL, and MySQL containers..env.memgraph– specific to the Memgraph service (set Bolt creds/ports here).
For local development without Docker, create a .env (or export vars in your shell). Core settings:
| Variable | Purpose |
|---|---|
SECRET_KEY |
Required; set to a long random string. |
DEBUG |
True for local development. |
DJANGO_ALLOWED_HOSTS |
Space-separated hostnames for Django. |
SQL_ENGINE |
Defaults to django.db.backends.sqlite3 for DATABASES['second']. Only override if you need another secondary DB. |
SQL_DATABASE, SQL_USER, SQL_PASSWORD, SQL_HOST, SQL_PORT |
Primary credentials reused for both PostgreSQL (default) and the optional legacy DB connection. |
PSQL_HOST, PSQL_PORT |
Allow using a separate host/port for PostgreSQL while keeping the other SQL_* values. |
DJANGO_CSRF_HOSTS |
Trusted origins for CSRF protection (space-separated). |
DATA_UPLOAD_MAX_MEMORY_SIZE |
Uses the default 40MB; override only when needed. |
| Variable | Purpose |
|---|---|
SMTP |
Set to a Django email backend (defaults to console). |
EMAIL_HOST, EMAIL_PORT, EMAIL_USER, EMAIL_PW |
SMTP credentials. |
| Variable | Purpose |
|---|---|
MEMGRAPH_HOST, MEMGRAPH_PORT, MEMGRAPH_USER, MEMGRAPH_PW |
Bolt connection info for server-side Memgraph clients (pulsekg/models.py, pulsekg/pymg_client.py). |
MEMGRAPH_URL |
Bolt URL used inside the LangChain chatbot (bolt://host:port). |
OLLAMA_URL |
HTTP endpoint for the Ollama daemon (default http://localhost:11434). |
OLLAMA_MODEL |
Chat model used by the skill generator (default gemma3:27b). |
EMBEDDING_MODEL |
Embedding model for vector search (default embeddinggemma:latest). |
Example .env.prod:
SECRET_KEY=replace-me
DEBUG=False
DJANGO_ALLOWED_HOSTS=localhost 127.0.0.1
SQL_DATABASE=pulsecrm
SQL_USER=pulsehub
SQL_PASSWORD=supersecret
PSQL_HOST=postgresql
PSQL_PORT=5432
MEMGRAPH_URL=bolt://memgraph:7687
MEMGRAPH_HOST=memgraph
MEMGRAPH_PORT=7687
OLLAMA_URL=http://host.docker.internal:11434
OLLAMA_MODEL=gemma3:27b
EMBEDDING_MODEL=embeddinggemma:latest
EMAIL_HOST=smtp.example.com
EMAIL_PORT=587
EMAIL_USER=no-reply@example.com
EMAIL_PW=mailsecret
DJANGO_CSRF_HOSTS=http://localhost:6001- Create a virtualenv
python3 -m venv .venv source .venv/bin/activate pip install --upgrade pip pip install -r requirements.txt - Configure databases
- Start PostgreSQL + Memgraph locally or via Docker.
- For quick smoke tests you can point
DATABASES['default']to SQLite by settingSQL_ENGINE=django.db.backends.sqlite3and omittingPSQL_*, but features that rely on PostgreSQL (pgvector) will not work.
- Apply migrations & collect static assets
python manage.py migrate python manage.py collectstatic python manage.py createsuperuser
- Run supporting services
- Ensure Ollama is running with the required models pulled (
ollama pull gemma3:27b embeddinggemma:latest llama3.2-vision). - Start Memgraph (
memgraph/memgraph-mageDocker image works) and create any required vector indexes.
- Ensure Ollama is running with the required models pulled (
- Start Django
Visit
python manage.py runserver
http://127.0.0.1:8000/for the CRM and/pulsekg/routes for KG tools.
- Copy
.env.prod&.env.memgraphas described above. - Build and start the stack:
docker compose up --build -d
- Services:
web: Django + Gunicorn (runsentrypoint.sh, exposes port8000inside the network).nginx: Serves onhttp://localhost:6001, proxies to Gunicorn, and serves/static/+/media/.postgresql: pgvector-enabled Postgres (volumepg_data).db: MySQL (only needed for legacy data import;docker-compose-test.yamlcan seed it frompulsecrm.sqlif provided).memgraph:memgraph/memgraph-mageimage with health check and Bolt (7687) / HTTP (7444) ports. Adjust.env.memgraphif you secure it.
- To expose database ports for local tooling, use
docker-compose-test.yaml:This variant also mounts a SQL dump into MySQL for local experiments and maps PostgreSQL (docker compose -f docker-compose-test.yaml up --build
5432), Memgraph (7688/7445), and MySQL ports to the host. - Logs & management:
docker compose logs -f web docker compose exec web python manage.py createsuperuser docker compose down -v # remove volumes if you want a clean slate
- Memgraph: Required for all
pulsekgfeatures. When running locally without Docker, start it viadocker run -p 7687:7687 -p 7444:7444 memgraph/memgraph-mage. The app expects people/projects/skills nodes to exist; use the admin views (/pulsekg/create-person,/pulsekg/admin-assign-project) orMemgraphServicehelper methods to seed data. - Ollama: Install from https://ollama.com, start
ollama serve, and pull the models you reference in env vars. Business-card scanning requires a multimodal model (llama3.2-vision), while skill extraction/chat use text models. - pgvector: Enable the extension in PostgreSQL (
CREATE EXTENSION IF NOT EXISTS vector;) before running migrations if you plan to store vector data.
- CRM (app):
- Navigate to
/personen,/unternehmen,/branchen,/interaktionfor CRUD. - Use the global search (
/search/) which queries people, companies, and interactions simultaneously (app/views.py:48). - Export contacts via
/personen/exportor/unternehmen/<id>/export(CSV or Outlook format viaapp/utils.py:6). - User management under
/user/integrates with Memgraph: on creation/edit staff users can opt-in to automatically syncing a person node (app/views.py:292).
- Navigate to
- Business card workflow:
- Upload images at
/scan/.BusinessCardUploadViewstores the file inMEDIA_ROOT/tmp/, callsextract_business_card_info(Ollama vision), and pre-fills both person + company forms. - Confirm/edit the extracted fields and submit; forms route to
BusinessCardProcessViewwhich persists both models.
- Upload images at
- Knowledge graph dashboards (pulsekg):
/pulsekg/dashboardshows the logged-in user’s skills/projects/repos/publications read from Memgraph./pulsekg/manage_*endpoints let users add/remove relationships by reusingMemgraphService.- Staff-only helpers create standalone nodes and assign projects.
/pulsekg/graph-data/returns nodes/edges for visualisations, while/pulsekg/chat/hosts the LangChain chat UI.
- Skill generation:
/pulsekg/generate-skills/<type>/(types:pub,project,repo,subproject) runsmine_skillswhich sends prompts (seepulsekg/prompt_library/*.txt) to Ollama. Confirmed skills are ingested into Memgraph through helper functions inmemgraph_tools.py.
- Chatbot:
- Chat POST requests hit
pulsekg.views.chat_view. The LangChain agent runs tool calls (run-cypher-query,get-vector-indices,vector-search) and validates every Cypher query so only read-only operations reach Memgraph (pulsekg/cypher_validator.py).
- Chat POST requests hit
- Run the Django test suite (currently minimal) with:
python manage.py test app pulsekg - Check migrations:
python manage.py makemigrations python manage.py migrate
- Collect static assets when deploying:
python manage.py collectstatic --no-input
- Cannot connect to Memgraph: Confirm
MEMGRAPH_HOST/PORTandMEMGRAPH_URLline up. When using Docker, set them to the service name (memgraph) and ensure Bolt is exposed if you connect from the host. - Ollama errors: Make sure
ollama serveis running and the requested model is pulled. SetOLLAMA_URLtohttp://host.docker.internal:11434when the Django container must reach a host daemon. - Static files missing in Docker: Run
docker compose exec web python manage.py collectstatic --no-inputif the entrypoint was skipped, and ensure thestaticvolume is mounted to Nginx. - MySQL migration issues: Use the
DATABASES['second']connection as a read-only handle to the legacy DB and follow the dedicated migration guide. - Business card extraction fails: Verify the uploaded image is reachable under
MEDIA_ROOT/tmp/and that the Ollama vision model supports images (update to the latest Ollama release if needed).
- Seed Memgraph with base data (people, skills, projects) so dashboards and chat have context.
- Configure SMTP creds if you plan to send password resets (
CustomPasswordResetView).