Development Guide
Essential information for developing DeepRetro.
Setup
git clone <repository-url>
cd DeepRetro
uv sync --project deepretro --extra dev --extra docs
The deepretro package metadata is the source of truth for CI and local
developer environments. The docs workflow installs the package with its
docs extra and builds documentation from docs/ with
uv run --project ../deepretro.
Project Structure
DeepRetro/
├── src/ # Main source code
│ ├── api.py # Flask API server (main entry point)
│ ├── main.py # Core retrosynthesis function
│ ├── cache.py # Caching functionality
│ ├── prithvi.py # Core retrosynthesis logic
│ ├── rec_prithvi.py # Recursive retrosynthesis
│ ├── metadata.py # Metadata extraction
│ └── utils/ # Utility modules
├── viewer/ # Web interface
├── tests/ # Test suite
└── docs/ # Documentation
Development Workflow
Create feature branch:
git checkout -b feature/your-feature-name
Make changes following code standards
Run tests:
python -m pytest tests/
Submit pull request
Code Standards
Follow PEP 8
Use type hints
Add docstrings (Google style)
Keep functions focused
Example:
def process_molecule(smiles: str, model: str) -> Dict[str, Any]:
"""Process molecule with specified model.
Args:
smiles: SMILES string
model: Model identifier
Returns:
Processing results
"""
return result
Testing
Unit Tests:
def test_parse_response():
response = "test response"
result = parse_response(response)
assert result is not None
Integration Tests:
def test_retrosynthesis_api():
response = client.post(
'/api/retrosynthesis',
headers={'X-API-KEY': 'test-key'},
json={'smiles': 'CC'}
)
assert response.status_code == 200
Mock External Services:
@patch('src.utils.llm.call_LLM')
def test_llm_integration(mock_llm):
mock_llm.return_value = '{"result": "test"}'
result = process_with_llm("test")
assert result is not None
Adding Features
New LLM Model:
Add to variables.py:
NEW_MODELS = ["new-model-name"]
Update api.py model selection
Add provider logic in llm.py
New Validation:
Create validation function
Add to main function with flag
Update API endpoint parameters
New AiZynthFinder Model:
Add to AZ_MODEL_LIST in variables.py
Update model validation in api.py
Error Handling
Use structured error handling:
try:
result = process_data(input_data)
except ValueError as e:
return jsonify({"error": str(e)}), 400
except Exception as e:
logger.error(f"Unexpected error: {e}")
return jsonify({"error": "Internal server error"}), 500
Logging
Use structured logging:
import structlog
log = structlog.get_logger()
log.info("Processing molecule", smiles=smiles, model=model)
Documentation
Update docstrings for new functions
Update user guide for new features
Update API documentation if needed
Keep README current
For contribution guidelines, see Contributing Guide.