Code Monkey home page Code Monkey logo

uk-pv-national-gsp-api's Introduction

Nowcasting API

All Contributors

codecov

API for hosting nowcasting solar predictions. Will just return 'dummy' numbers until about mid-2022!

We use FastAPI.

Documentation

Documentation can be viewed at /docs or /swagger. This is automatically generated from the code.

Setup and Run

This can be done it two different ways: With Python or with Docker.

Python

Create a virtual env

python3 -m venv ./venv
source venv/bin/activate

Install Requirements and Run

pip install -r requirements.txt
cd src && uvicorn main:app --reload

You may need to run the following additional installation pip install git+https://github.com/SheffieldSolar/PV_Live-API#pvlive_api for pvlive-api, as in the Dockerfile.

Docker

  1. Make sure docker is installed on your system.
  2. Use docker-compose up in the main directory to start up the application.
  3. You will now be able to access it on http://localhost:80

Tests

TO run tests use the following command

docker stop $(docker ps -a -q)
docker-compose -f test-docker-compose.yml build
docker-compose -f test-docker-compose.yml run api

Development

We use pre-commit to manage various pre-commit hooks. All hooks are also run as Actions when code is pushed to GitHub.

You can run the formatters and linters locally. To do that:

  1. Install pre-commit
  2. Check the install worked via pre-commit --version
  3. Install the git hooks script via pre-commit install

Deployment

Deployment of this service is now done through terraform cloud.

Environmental Variables

  • AUTH0_DOMAIN - The Auth0 domain which can be collected from the Applications/Applications tab. It should be something like 'XXXXXXX.eu.auth0.com'
  • AUTH0_API_AUDIENCE - THE Auth0 api audience, this can be collected from the Applications/APIs tab. It should be something like https://XXXXXXXXXX.eu.auth0.com/api/v2/
  • DB_URL- The Forecast database URL used to get GSP forecast data
  • DB_URL_PV - The PV database URL, used to get PV data
  • ORIGINS - Endpoints that are valid CORS origins. See FastAPI documentation.
  • N_HISTORY_DAYS - Default is just to load data from today and yesterday, but we can set this to 5, if we want the api always to return 5 days of data
  • FORECAST_ERROR_HOURS - using route /v0/system/GBstatus/check_last_forecast_run we can check if a forecast has been made in the last FORECAST_ERROR_HOURS hours
  • ADJUST_MW_LIMIT - the maximum the api is allowed to adjust the national forecast by

Routes to SQL tables

National

  graph TD;
      N1(national/forecast) --> Q1;
      Q1{Include metadata?>} -->|no| Q2;
      Q1 --> |yes| N2[NationalForecast];
      N4[ForecastValueLatest];
      Q2{forecast horizon <br> minutes not None}
      Q2-->|yes| N5[ForecastValueSevenDays];
      Q2-->|no| N4;

      NP1(national/pvlive)-->NP2;
      NP2[GSPYield];

GSP

  graph TD;
      G1(gsp/forecast/all);
      G1--> N3[ManyForecasts];

      G3(gsp/gsp_id/forecast) -->Q4;
      Q4{forecast horizon <br> minutes not None}
      Q4-->|yes| G7[ForecastValueSevenDays];
      Q4-->|no| G6[ForecastValueLatest];

      GP1(gsp/pvlive/all)-->GP2;
      GP2[LocationWithGSPYields];

      GP3(gsp/gsp_id/pvlive)-->GP4;
      GP4[GSPYield];

Extras

  graph TD;
      G1(status)-->G2;
      G2[Status];

      G3(gsp)-->G4
      G4[Location]

Contributors ✨

Thanks goes to these wonderful people (emoji key):

Peter Dudfield
Peter Dudfield

πŸ’»
Mohammed Faisal
Mohammed Faisal

πŸ’»
Bodale Denis
Bodale Denis

πŸ’»
Souhit Dey
Souhit Dey

πŸ’»
Flo
Flo

πŸ’»
Shanmukh
Shanmukh

πŸ’»
Sixte de Maupeou
Sixte de Maupeou

πŸ’»
rachel tipton
rachel tipton

πŸ’»
braddf
braddf

πŸ’»
Dorin
Dorin

πŸ‘€
Peter Hull
Peter Hull

πŸ’»
Pedro Garcia Rodriguez
Pedro Garcia Rodriguez

πŸ’»

This project follows the all-contributors specification. Contributions of any kind welcome!

uk-pv-national-gsp-api's People

Contributors

allcontributors[bot] avatar aryanbhosale avatar bodaledenis avatar braddf avatar breakingpitt avatar dctanner avatar devsjc avatar flowirtz avatar jackkelly avatar jacobbieker avatar mdfaisal98 avatar obitorasu avatar peterdudfield avatar petermnhull avatar pre-commit-ci[bot] avatar rachel-labri-tipton avatar sixtedemaupeou avatar vnshanmukh avatar

Stargazers

 avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

uk-pv-national-gsp-api's Issues

`Release` emails are from "Peter Dudfield" in `nowcasting_api`, but are from "github-actions[bot]" for all OCF's other repos

This really isn't very important, and I'm being selfish by even mentioning this! I bring this up because it breaks my gmail filters πŸ™‚

This issue is about the automated "Release" emails we receive (with subjects like "[openclimatefix/nowcasting_api] Release 0.1.14 - v0.1.14").

In all our other repositories, the "Release" emails are from "github-actions[bot]", as can be seen in this screenshot from gmail:

image

But, for some reason, nowcasting_api's "Release" emails are from "Peter Dudfield":

image

I was just wondering if we can change the "sender" from "Peter Dudfield" to "github-actions[bot]"? Or have GitHub changed something that's out of our control?! πŸ™‚

Add CORS Configuration

For our frontend to be able to send requests to the API we need to configure CORS.

There is a good guide on this in the docs.

For now, I propose that we should allow the following origins:

origins = [
    "http://localhost:3002",  # TODO: Remove this in production and only allow in dev
    "https://app.nowcasting.io"
]

Expose GSP data

Detailed Description

Expose GSP level data

Context

Good for front end to have access to data,
This although this could be done through Sheffield Solar, but the intermediate PV values are not stored

Possible Implementation

get data from yesterday 00.00
don't worry about time searching

Add historic route

Good to add endpoint that gives the latest forecast of the past

Detailed Description

Would be nice to see the forecast from yesterday, but just show the last forecast made.
This is useful for comparing to pvlive 'truth' values.

Optional inputs can be 'dateFrom' and 'dateTo'. This could default to yesterday to tomorrow

Add status get and post method

Good to have a status get method.

This will be handy for displaying to the user at some point

We could have:

  • {'status':'ok','message=''}
  • {'status'error': 'message', 'Satellite data is down'}
  • {'status':'warning', 'Satellite data is down, so using model v1.01 instead'}

This would involve making a

Model

  1. Pydantic model / sqlmodel in `nowcatsing_datamodel'

class StatusSQL(CreatedMixin):
    """ffffffff"""

    __tablename__ = "status"

    id = Column(Integer, primary_key=True)
    status = Column(String)
    message = Column(String)

class Status(EnhancedBaseModel):
    """"""

    status: string = Field(
        ...,
        description="ggggg",
    )
    message: str = Field(
        ..., description="The forecasted value in MW"
    )
 
+ validate on status in 'ok', 'warning', 'error'

tests

  • check status object can be made, and move to pydantic object
  • check validation makes error when status is 'laugh'

Read function

  1. create a read last function in `nowcatsing_datamodel' - see other read examples

tests

  • make 2 lots dummy data and check last one is read

API

  1. create api end point to expose this in `nowcatsing_api'

tests

  • add dummy data, and check end points works

Get latest GSP route for today and yesterday

Detailed Description

Provide a route to give latest values of the forecast for today and yesterday

Possible Implementation

Might need to get List of 'ForecastValues' Rather than a Forecast

0s to random

Detailed Description

Change zeros to random numbers, lower limit zero

Context

Useful to be able to plot these numbers. A plot of zeros is very dull

Possible Implementation

using numpy

Address Review Comments from Design Review Session

Based on our design review earlier this week, we should address the following comments:

  • Check naming convention around effective_time etc. - what is this called in the meteorology world? target_time?
  • Add a new field β€œmetadata” that gives information about what the age of the latest data per data input is, e.g. They should be timestamps
inputDataAge {
    "pv": β€œ2009-10-31T01:48:52Z”
    "satellite": β€œ2009-10-31T01:48:52Z”
}
  • Consider putting country codes into the domain eg gb
  • Create a separate endpoint to expose national forecast, eg /forecasts/gb/national
  • Add pv as a part of the URL. So the route might be v0/forecast/gb/pv/[national,gsp]
  • Rename forecasted_values to forecast_values
  • Add? Expectations

Also see #24.

API: Re define API routes

After reviewing, we shall go for this:

/v0/solar/GB/national/forecast/
/v0/solar/GB/national/pvlive/
/v0/solar/GB/gsp/forecast/all
/v0/solar/GB/gsp/forecast/{gsp_id}
/v0/solar/GB/gsp/forecast/{gsp_id}/{only_values} or other filter parameters
/v0/solar/GB/gsp/pvlive/{gsp_id}
/v0/system/GB/gsp/boundaries
/v0/system/GB/gsp/

TODOs (in the future)
/v0/wind/GB/
/v0/solar/site/
/v0/IT/

Tasks

National

  • Split national functions into separate file called 'national'.py' and rename routes ( + update tests). You need to add a route in 'main.py'. Around line 97 - app.include_router(national_router, prefix=f"{v0_route}/national")

'/forecast/national' --> 'forecast'
'/pvlive/national' --> 'pvlive'
new route prefix is /v0/solar/GB/national

System

  • Split system functions into separate file and rename routes ( + update tests)

  • /v0/system/GB/gsp/boundaries

  • /v0/system/GB/gsp/

new route prefix is /v0/system/GB/

GSP

  • Update gsp routes ( + updates tests)

'/forecast/all/' --> 'forecast/all' (same)
'/forecast/one_gsp/{gps_id}' --> 'forecast/{gps_id}'
'/pvlive/one_gsp/{gsp_id}' --> 'pvlive/{gsp_id}'
same route prefix is /v0/solar/GB/gsp

Extra merge

  • merge these routes
  1. '/v0/GB/solar/gsp/forecast/latest/{gsp_id}'
  2. '/v0/GB/solar/gsp//forecast/one_gsp/{gps_id}'

Automatically Release Docker Image Using GitHub Actions

Automated deploy docker image to docker hub

Detailed Description

Every push, a docker image should be made and pushed to docker hub
Would be great to have it versioned tag too

Context

Useful for automatic deployment

Possible Implementation

For 2. we could try basing it off of SatFlows which publishes to Docker Hub and GitHub Container Repo on every push

Add security

Add API security

This can be done with Auth0, The Nwocasting App will need update as it will need to pull some credentials when pulling the API

TODO addAuth0 reference docs

  1. First pass security
  2. add permission and roles

Add route for PV data

Detailed Description

Add route to expose PV api data

Context

So front end can plot api data

Possible Implementation

  • get last 24 hours fo data, time searching can happen later

Upgrade datamodel

Upgrade nowcasting_datamodel to 0.0.53

This was a small change to do with making location.gsp_id a distinct columns

Add route GSP capacity

Detailed Description

Get GSP capacity details

Context

This is so we can show the % of power being generated

Possible Implementation

provide list of GSPSystems. Need to add capacity to GSP systems in the data model, and update GSP consumer to load capacity

Reduce size of docker file

Detailed Description

The current docker file is ~ 600MB - docker hub.
It would be great to reduce this if possible.

Context

Good to keep docker files

Possible Implementation

Perhaps dont isntlal packages that are used. Might have to do someting in nowcasting_dataset

Push docker file to dockerhub

Detailed Description

On release to main, push docker file to docker hub

Context

The docker file can be then be used for deployment

Possible Implementation

....

Add route timing

Would be great to see how long the routes took to run

the example here probably would be good

API: Reduce docker size

Detailed Description

The current docker file is ~ 600MB - docker hub.
It would be great to reduce this if possible.

Context

Good to keep docker files

Possible Implementation

Perhaps dont install packages that are used. Might have to do something in nowcasting_forecast

Speed up normalize route

Detailed Description

Current the /v0/GB/solar/gsp/forecast/all with normalize == True takes ~10 seconds. This is to long.

Context

Would be good for FE if ~1 second

Possible Implementation

slow part is the looping in the pydantic model, to normalize data. We could:

  • Save the data and add a 'normalize' flag. This would double the amount of data in the database, but make for quick reading
  • Paralize the processing - here. Not sure if setup up parrallel costs would make it speed up
  • Try to convert pydantic models to flat pandas frames, then operate on one column, then convert back to pydantic models
  • Add validation method to pydanitc model, use if normalize do this.
  • Other options ...

read values from Database

Detailed Description

Read GSp results from database

Context

The GSP results are made by the ML models

Possible Implementation

import nowcasting_forecast and use the database folder to import the sqlalchemy datamodel and connection details.

Add logging

Detailed Description

Would be nice to have logging on when the routes are hit and with what variables. Would be great if they are piped through to AWS Cloudwatch - but I think this happens automatically if set up in the correct way

slow query when first starting api

SELECT DISTINCT ON (forecast_value.target_time) forecast_value.created_utc AS forecast_value_created_utc, forecast_value.id AS forecast_value_id, forecast_value.target_time AS forecast_value_target_time, forecast_value.expected_power_generation_megawatts AS forecast_value_expected_power_generation_megawatts, forecast_value.forecast_id AS forecast_value_forecast_id 
FROM forecast_value JOIN forecast ON forecast.id = forecast_value.forecast_id JOIN location ON location.id = forecast.location_id 
WHERE forecast_value.target_time >= '2022-08-23T00:00:00'::timestamp AND forecast_value.created_utc >= '2022-08-22T00:00:00'::timestamp AND forecast.created_utc >= '2022-08-22T00:00:00'::timestamp AND location.gsp_id = 0 ORDER BY forecast_value.target_time, forecast_value.created_utc DESC

This query first apperas when we start the the web page.
Need to find out where an dwhat call this. It should use forecast_value_latest not forecast value

Add test for floor_30_minutes_dt

Detailed Description

Add a few tests to make sure 'floor_30_minutes_dt' is working corectly.

Context

This is needed in order to find the rounded down half an hour, when querying the api for the latest forecast

Possible Implementation

see other test structure

Run CI every Monday

Scheudle CI test runner to run every monday lunctime

Context
useful to regular check things are broken

Possible Implementation

on:
  push:
  schedule:
    - cron: "0 12 * * 1"

Add elastic beanstalk files

Detailed Description

Add elastic beanstalk files into github. This means anyone with correct access to AWS can deploy the app.

Context

  • Useful if a quick update needs to be made
  • this might change with #31

Deploy Nowcasting API to AWS

Deploy this api to AWS using terraform

Detailed Description

Would be greta to have terraform to deploy this app to AWS.

Context

As part of 'Nowcasting' Project want to be able to deploy this automatically using terraform

Possible Implementation

  • Could be to deploy to elastic beanstalk, or to ECS. My feeling is elastic beanstalk will be easier
  • Make new IAM role
  • Add VPC, or take vpc_id
  • Add security group
  • ....

Add coverage badge

Detailed Description

Would be great to have a coverage badge on the main page

Context

Possible Implementation

coverallsapp/github-action#30

  • name: Coveralls
    env:
    GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
    run: |
    coveralls

Normalize forecasts

Detailed Description

Option to Normalize forecasting

Context

Good to deploy where it does nothing,

Possible Implementation

Then normalize by GSP capacity value. This is in the locationSQL object

Missing HTTPS Redirection

Describe the bug
Currently we are not redirecting http traffic (port 80) to be https instead (port 443).
This is because of a missing configuration in our Elastic Beanstalk deployment.

The API can already be reached over SSL via https://api.nowcasting.io (or api-dev respectively).
Additionally, however, we should be upgrading http connections as well.

To Reproduce
Steps to reproduce the behaviour:

  1. Go to '...'
  2. See Not Secure in browser navigation bar

Expected Behaviour
All connections to http://nowcasting-api... get redirected to https://nowcasting-api...

Additional Context
This can be resolved by following this AWS Guide.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. πŸ“ŠπŸ“ˆπŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.