A Python-based GraphQL API for managing generic sensor data with PostgreSQL database integration.
- GraphQL API with Strawberry GraphQL
- Generic Sensor Data Model supporting various sensor types
- PostgreSQL Integration with SQLAlchemy ORM
- Time-series Data Storage optimized for sensor readings
- Location Hierarchy support for organizing sensors
- Alert System for monitoring sensor values
- Database Migrations with Alembic
- FastAPI Backend with automatic OpenAPI documentation
The API supports a flexible data model for sensor management:
- SensorType: Defines types of sensors (temperature, humidity, pressure, etc.)
- Location: Hierarchical location management (buildings, floors, rooms)
- Sensor: Individual sensor devices with metadata
- SensorReading: Time-series sensor measurements
- Alert: Automated alerts based on sensor conditions
- Generic Design: Support any type of sensor with configurable data types
- Hierarchical Locations: Organize sensors in a tree structure
- Time-series Optimization: Efficient storage and querying of sensor readings
- Alert Management: Configurable thresholds and alert conditions
# Make setup script executable and run it
chmod +x setup.sh
./setup.sh
# Activate virtual environment
source .venv/bin/activate- Copy the environment template:
cp .env.example .env- Edit
.envfile with your Aiven PostgreSQL connection details:
DATABASE_URL=postgresql://username:password@hostname:port/database_name# Create initial migration
alembic revision --autogenerate -m "Initial migration"
# Apply migrations
alembic upgrade headpython main.pyThe API will be available at:
- GraphQL Playground: http://localhost:8000/graphql
- API Documentation: http://localhost:8000/docs
- Health Check: http://localhost:8000/health
mutation {
createSensorType(input: {
name: "Temperature"
description: "Temperature sensor in Celsius"
unit: "°C"
dataType: "float"
minValue: -40.0
maxValue: 85.0
}) {
id
name
unit
}
}mutation {
createLocation(input: {
name: "Building A"
description: "Main office building"
address: "123 Main St"
city: "Helsinki"
country: "Finland"
}) {
id
name
}
}mutation {
createSensor(input: {
deviceId: "TEMP001"
name: "Office Temperature Sensor"
sensorTypeId: "sensor-type-id"
locationId: "location-id"
manufacturer: "SensorCorp"
model: "TC-100"
}) {
id
deviceId
name
}
}mutation {
createSensorReading(input: {
sensorId: "sensor-id"
value: 22.5
}) {
id
value
timestamp
}
}query {
sensors(locationId: "location-id") {
id
name
deviceId
sensorType {
name
unit
}
location {
name
}
latestReading {
value
timestamp
quality
}
}
}query {
sensorReadings(
sensorId: "sensor-id"
limit: 100
startTime: "2024-01-01T00:00:00Z"
endTime: "2024-01-02T00:00:00Z"
) {
value
timestamp
quality
}
}sensorapi/
├── app/
│ ├── core/
│ │ ├── __init__.py
│ │ └── config.py # Application configuration
│ ├── database/
│ │ ├── __init__.py
│ │ ├── database.py # Database connection
│ │ └── models.py # SQLAlchemy models
│ ├── graphql/
│ │ ├── __init__.py
│ │ ├── types.py # GraphQL types
│ │ ├── resolvers.py # GraphQL resolvers
│ │ └── schema.py # Main GraphQL schema
│ └── __init__.py
├── alembic/ # Database migrations
├── main.py # Application entry point
├── requirements.txt # Python dependencies
├── setup.sh # Environment setup script
├── .env.example # Environment template
├── .gitignore
└── README.md
The database schema is designed for efficient time-series data storage:
- Indexed columns for fast time-based queries
- UUID primary keys for distributed systems
- JSON columns for flexible metadata storage
- Hierarchical locations with parent-child relationships
- Quality indicators for data reliability tracking
pytestblack .
isort .mypy .For production deployment:
- Set
DEBUG=Falsein environment variables - Configure proper CORS origins
- Use a production WSGI server like Gunicorn
- Set up proper logging and monitoring
- Configure database connection pooling
- Set up SSL/TLS termination
- Fork the repository
- Create a feature branch
- Make your changes
- Add tests
- Submit a pull request
MIT License