{"id":26766109,"url":"https://github.com/ucl/fludetector-flask","last_synced_at":"2025-10-15T12:37:18.917Z","repository":{"id":29689599,"uuid":"122489999","full_name":"UCL/fludetector-flask","owner":"UCL","description":"Website, REST API, and data processors for the fludetector service from UCL","archived":false,"fork":false,"pushed_at":"2022-09-16T17:45:24.000Z","size":150,"stargazers_count":2,"open_issues_count":8,"forks_count":3,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-03-28T20:19:05.376Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/UCL.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2018-02-22T14:32:14.000Z","updated_at":"2022-02-22T17:18:29.000Z","dependencies_parsed_at":"2023-01-14T15:27:51.034Z","dependency_job_id":null,"html_url":"https://github.com/UCL/fludetector-flask","commit_stats":null,"previous_names":[],"tags_count":8,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/UCL%2Ffludetector-flask","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/UCL%2Ffludetector-flask/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/UCL%2Ffludetector-flask/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/UCL%2Ffludetector-flask/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/UCL","download_url":"https://codeload.github.com/UCL/fludetector-flask/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":249072821,"owners_count":21208253,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2025-03-28T20:19:09.760Z","updated_at":"2025-10-15T12:37:13.863Z","avatar_url":"https://github.com/UCL.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# fludetector\n\nWebsite, REST API, and data processors for the fludetector service from UCL.\n\n## Installation\n\nThis project requires:\n\n- python 2.7\n- virtualenv\n- SQLite3\n- lzop\n\nYou'll need to grab the project's secrets from someone, place them in a `.env` file in the project's root.\nSomething like this:\n\n    $ cat .env\n    GOOGLE_API_KEY=...\n    ADMIN_USERNAME=...\n    ADMIN_PASSWORD=...\n    SECRET_KEY=...\n\nThis env file is where the sensitive data (e.g. API keys) live, they're not\ncommitted to the repo.\n\nOnce you have those, clone this repo, point your terminal at it and run:\n\n    $ ./scripts/init.sh\n\nThis will get most things sorted out for you. \n\nYou can now run the server locally:\n\n    $ ./scripts/serve.sh\n\nRead the `init.sh` script to see what it's up to. There are also other scripts\nin this directory that you might find useful.\n\n\n## Making Changes\n\nThe project is a fairly standard Flask app, so if you know Flask, you know how\nthis works:\n\n - `fludetector/sources/` is where the data sources (e.g. Google, CSV, Twitter) are defined\n - `fludetector/static/` holds the static web assets (CSS, JS, images, etc.)\n - `fludetector/templates/` holds the HTML templates, written using the Jinaj2 template language\n - `fludetector/app.py` is where the Flask app is created and the routes/views are defined\n - `fludetector/forms.py` is where the WTForms forms are defined, for interacting with the user via HTML forms\n - `fludetector/models.py` is where the SQLAlchemy ORM models are defined, for interacting with teh SQLite3 database\n - `fludetector/scripts.py` holds the functions that are executed from the command line using `flask CMD`\n\n### To the Database\n\nIf you need to change the database schema you should use SQLAlchemy and alembic.\n\nSimply change the model definitions in `models.py` and then run:\n\n    $ alembic revision -m 'DESCRIPTION OF CHANGES' --autogenerate\n\nThis will put a new migration file into `migrations/versions/`, read it over\nto make sure it's doing what you expect. In particular you might need to\nwrite some custom data migrations if you need to move data from other\ntables/columns.\n\nOnce the migration file is ready, run it like this:\n\n    $ alembic upgrade head\n\nThis will update your database to match your new schema. There's no need to\nrun this manually in production as the update script takes care of it for you.\n\n### To the API\n\nThe API's code is found in `/fludetector/app.py`, the main functions are\nprefixed with `api_`, for instance `api_scores` is the route function that\nreturns scores.\n\nIf you change the API, remember to update the docs page\n`fludetector/templates/docs.html`.\n\n### To the Templates\n\nThe templates are written using the Jinja2 template language. This means that\ndata can be passed in from the Python side of things and used to dynamically\ncreate HTML.\n\nIf you need to add more data into a template, look for the route function in\n`app.py` that renders the template file.\n\nMost of the templates extend the base template, or the admin base template. If\nyou need to add a new JS/CSS dependency it's probably best to add it to the\nbase template, as that's where the `\u003chead\u003e` is defined.\n\n### Deploying\n\nThere's a script in `scripts/` called `update.sh`, if you log into the\nproduction machine, `cd` to the project's folder and run that script then\neverything should be updated and deployed for you.\n\nThe update script pulls the latest changes from Gitlab. So don't make changes\ndirectly to the code base in the prod machine, make them locally, push your\nchanges, then update to deploy them.\n\n\n## TODO\n\n[ ] Get the Twitter data source/analysis working again\n[ ] Fix the update script so that the deploy user can restart the supervisor process for fludetector\n\n\n### Listing models and regions\n\nThe home page has a list of the models and the regions that you can query over,\nusing checkboxes to select which ones to include in your graph.\n\nBecause we're rendering a list of regions for each model in a list of models,\nwe're using nested for loops in the jinja2 template.\n\nBecause we're interested in a list of the selected models and regions, we're\nusing a FieldList in the WTForms form.\n\nUnfortunately, the FieldList demands that you order your fields like this\n`model_regions-INDEX`. Getting hold of the index in the nested for loops is\ntricky.\n\nHence the WTF in `home.html` where we use this hack: https://stackoverflow.com/questions/7537439/how-to-increment-a-variable-on-a-for-loop-in-jinja-template/32700975#32700975\nto build a counter.\n\n## Reporting bugs\n\nPlease use the GitHub issue tracker for any bugs or feature suggestions:\n\n\u003chttps://github.com/UCL/fludetector-flask/issues\u003e\n\n## Copyright\n\nFludetector is licensed under the GNU General Public License, v3. A copy of this license is included in the file [LICENSE.md](LICENSE.md).\n\n\u0026copy; 2019 UCL ([https://www.ucl.ac.uk](https://www.ucl.ac.uk)).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fucl%2Ffludetector-flask","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fucl%2Ffludetector-flask","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fucl%2Ffludetector-flask/lists"}