QuillSpace is a next-generation AI-powered writing workspace backend, designed to replace and surpass tools like Grammarly, Google Docs Smart Compose, and Microsoft Editor. It's not just a grammar checker — it's a Writing OS that edits ideas, structure, and outcomes.
- Document Management: Full CRUD operations for writing documents
- Version Control: Snapshot and restore document versions
- AI Writing Assistance: Rewrite, expand, shorten, outline, plan, score, and edit text
- Export Capabilities: Export to PDF and DOCX formats
- User Profiles: Customizable style profiles for personalized AI suggestions
- Production-Ready: Clean architecture, comprehensive tests, type hints throughout
- Language: Python 3.11+
- Framework: FastAPI
- Database: PostgreSQL (with SQLite support for development)
- ORM: SQLAlchemy 2.x
- Migrations: Alembic
- Testing: pytest + HTTPX
- Code Quality: black, isort, ruff
- Python 3.11 or higher
- PostgreSQL (optional, SQLite works for local dev)
- Clone the repository:
git clone <repository-url>
cd quillspace- Install dependencies:
make install
# or
pip install -r requirements.txt- Set up environment variables:
cp .env.example .env
# Edit .env with your database URL and other settings- Run database migrations:
make migrate
# or
alembic upgrade head- Run the development server:
make run
# or
uvicorn app.main:app --reload --host 0.0.0.0 --port 8000The API will be available at http://localhost:8000
Once the server is running, visit:
- Interactive API docs: http://localhost:8000/docs
- ReDoc: http://localhost:8000/redoc
curl -X POST http://localhost:8000/api/v1/documents \
-H "Content-Type: application/json" \
-H "X-User-Id: user_123" \
-H "X-User-Tier: PRO" \
-d '{
"title": "My First Document",
"content": "This is the content of my document."
}'curl -X POST http://localhost:8000/api/v1/ai/rewrite \
-H "Content-Type: application/json" \
-H "X-User-Id: user_123" \
-d '{
"text": "Make this sound more professional",
"instructions": "formal tone"
}'curl -X POST http://localhost:8000/api/v1/exports/pdf \
-H "Content-Type: application/json" \
-H "X-User-Id: user_123" \
-d '{
"document_id": "your-document-uuid"
}'make test
# or
pytest -vmake format
# or
black . && isort .make lint
# or
ruff check .make makemigration MSG="add new field"
# or
alembic revision --autogenerate -m "add new field"make install- Install dependenciesmake run- Run development servermake test- Run testsmake lint- Run lintersmake format- Format codemake makemigration MSG='message'- Create new migrationmake migrate- Apply migrationsmake clean- Clean up caches and temp files
quillspace/
├── app/
│ ├── api/
│ │ ├── deps.py # Dependency injection (auth, DB, etc.)
│ │ └── routes/ # API endpoints
│ ├── core/
│ │ ├── config.py # Configuration management
│ │ └── logging.py # Logging setup
│ ├── db/
│ │ ├── base.py # SQLAlchemy base
│ │ ├── session.py # Database session
│ │ └── init_db.py # DB initialization
│ ├── models/ # SQLAlchemy models
│ ├── schemas/ # Pydantic schemas
│ ├── services/ # Business logic
│ ├── utils/ # Utility functions
│ └── main.py # FastAPI app entry point
├── alembic/ # Database migrations
├── tests/ # Test suite
├── requirements.txt
├── Makefile
└── README.md
The current implementation uses a simple header-based auth stub:
X-User-Id: User identifier (defaults to "user_demo")X-User-Tier: User tier (defaults to "TRIAL")
This is designed to be replaced with JWT or QuillConnect integration in production.
See .env.example for all available configuration options:
ENV: Environment name (local, staging, production)DEBUG: Debug mode (true/false)DATABASE_URL: Database connection URLOPENAI_API_KEY: OpenAI API key (optional, uses FakeAIClient if not set)DEFAULT_USER_TIER: Default tier for users
This backend is designed to be deployed on platforms like:
- Replit
- Heroku
- AWS (ECS, Lambda)
- Google Cloud Run
- Railway
- Render
A Dockerfile can be added for containerized deployments.
- Fork the repository
- Create a feature branch
- Make your changes
- Run tests and linting
- Submit a pull request
[Specify your license here]
For issues and questions, please open a GitHub issue.