A RESTful API service for managing environmental sensor data and campaigns.
-
Clone the repository
-
Install dependencies (Docker and Docker Compose required)
-
Create a virtual environment and install dependencies:
python -m venv .venv source .venv/bin/activate pip install -r requirements.txt pip install -r requirements-dev.txt -
Create a
.envfile and set the environment variables:cp .env.sample .env
-
Start containers:
docker compose up -d
or
docker compose -f docker-compose.dev.yml up -d
or just the database:
docker compose -f docker-compose.dev.yml up -d db
-
Initialize the database:
# Run database migrations alembic upgrade head -
Run the application for development:
fastapi dev app/main.py
-
SSH to the VM with your TACC credentials:
ssh <tacc_username>@upstream-dso.tacc.utexas.edu
-
Switch to root:
sudo su
-
Enter to the prod directory or dev directory depending on what you want to do:
cd ~/upstream-dev cd ~/upstream-prod
-
Change the IMAGE_TAG (commit hash, e.g. sha-a0fe1e7) in the .env file. You can find here the latest commit hash.
vim .env
-
Restart the containers:
docker-compose up -d
There are two instances running on upstream-dso.tacc.utexas.edu:
- Production: https://upstream-dso.tacc.utexas.edu/docs/
- Development: https://upstream-dso.tacc.utexas.edu/dev/docs/
The project uses Alembic for database migrations. Key commands:
# Create a new migration
alembic revision --autogenerate -m "description"
# Apply migrations
alembic upgrade head
# Rollback last migration
alembic downgrade -1
# View migration history
alembic historyThe following diagram shows the relationships between the main entities in the system:
classDiagram
class Campaign {
+int campaignid
+string campaignname
+string contactname
+string contactemail
+string description
+datetime startdate
+datetime enddate
+string allocation
}
class Station {
+int stationid
+string stationname
+string description
+string contactname
+string contactemail
+bool active
+datetime startdate
}
class Sensor {
+string alias
+string description
+bool postprocess
+string postprocessscript
+string units
}
class Measurement {
+int measurementid
+int sensorid
+string variablename
+datetime collectiontime
+string variabletype
+string description
+number measurementvalue
}
Campaign "1" --> "*" Station : has
Station "1" --> "*" Sensor : contains
Sensor "1" --> "*" Measurement : records