Raw Method Generation
Imports
#exports
import pandas as pd
import io
import yaml
import xmltodict
from jinja2 import Template
from IPython.display import JSON
from ElexonDataPortal.dev import specgen
import os
from dotenv import load_dotenv
assert load_dotenv('../.env'), 'Environment variables could not be loaded'
api_key = os.environ['BMRS_API_KEY']
API_yaml = specgen.load_API_yaml(fp='../data/BMRS_API.yaml')
JSON(API_yaml)
<IPython.core.display.JSON object>
Raw Method Generation
#exports
dict_head = lambda dict_, n=5: dict(pd.Series(dict_).head(n))
def clean_path_name(
    path_name: str='/BMRS/B0610/v1',
    name_components_to_drop: list=['BMRS', 'v1', 'v2']
):
    for name_component_to_drop in name_components_to_drop:
        path_name = path_name.replace(name_component_to_drop, '')
    path_name = path_name.strip('/')
    return path_name
path_name = '/BMRS/B0610/v1'
clean_path_name(path_name)
'B0610'
#exports
def get_available_methods(
    API_yaml: dict, 
    path: str,
    acceptable_methods: list=['get', 'post', 'put', 'head', 'delete', 'patch', 'options']
):
    path_keys = API_yaml['paths'][path].keys()
    available_methods = list(set(path_keys) - (set(path_keys) - set(acceptable_methods)))
    return available_methods
def extract_parameter_example(parameter):
    if 'examples' in parameter.keys():
        examples = [value['value'] for value in parameter['examples'].values()]
        example = examples[0]
    else:
        example = parameter['example']
    return example
def construct_parameters(method_details):    
    parameters = list()
    for parameter in method_details['parameters']:
        parameter_info = dict()
        parameter_info['name'] = parameter['name']
        parameter_info['type'] = parameter['schema']['type']
        parameter_info['example'] = extract_parameter_example(parameter)
        parameters += [parameter_info]
    return parameters
def construct_path_functions(API_yaml, path):
    functions = list()
    root_url = API_yaml['servers'][0]['url']
    available_methods = get_available_methods(API_yaml, path)
    for method in available_methods:
        function = dict()
        method_details = API_yaml['paths'][path][method]
        function['name'] = f'{method}_{clean_path_name(path)}'
        function['endpoint'] = f'{root_url}{path}'
        function['description'] = method_details['description']
        function['parameters'] = construct_parameters(method_details)
        functions += [function]
    return functions
def construct_all_functions(API_yaml):
    functions = list()
    for path in API_yaml['paths']:
        functions += construct_path_functions(API_yaml, path)
    return functions
functions = construct_all_functions(API_yaml)
functions[0]
{'name': 'get_B0610',
 'endpoint': 'https://api.bmreports.com/BMRS/B0610/v1',
 'description': 'Actual Total Load per Bidding Zone',
 'parameters': [{'name': 'APIKey', 'type': 'string', 'example': 'AP8DA23'},
  {'name': 'SettlementDate', 'type': 'string', 'example': '2021-01-01'},
  {'name': 'Period', 'type': 'string', 'example': '1'},
  {'name': 'ServiceType', 'type': 'string', 'example': 'csv'}]}
#exports
def save_methods(
    functions: list,
    in_fp: str='../templates/raw_methods.py',
    out_fp: str='../ElexonDataPortal/dev/raw.py'
):
    rendered_schema = Template(open(in_fp).read()).render(functions=functions)
    with open(out_fp, 'w') as f:
        try:
            f.write(rendered_schema)
        except e as exc:
            raise exc
save_methods(functions)
from ElexonDataPortal.dev import raw
r = raw.get_B1610(
    APIKey=api_key, 
    SettlementDate='2020-01-01', 
    Period=1,
    NGCBMUnitID='*', 
    ServiceType='csv'
)
pd.read_csv(io.StringIO(r.text), skiprows=1).head(3)
| Time Series ID | Registered Resource EIC Code | BM Unit ID | NGC BM Unit ID | PSR Type | Market Generation Unit EIC Code | Market Generation BMU ID | Market Generation NGC BM Unit ID | Settlement Date | SP | Quantity (MW) | 
| ELX-EMFIP-AGOG-TS-319 | 48W00000LNCSO-1R | T_LNCSW-1 | LNCSO-1 | Generation | 48W00000LNCSO-1R | T_LNCSW-1 | LNCSO-1 | 2020-01-01 | 1 | 56.076 | 
| ELX-EMFIP-AGOG-TS-320 | 48W00000LNCSO-2P | T_LNCSW-2 | LNCSO-2 | Generation | 48W00000LNCSO-2P | T_LNCSW-2 | LNCSO-2 | 2020-01-01 | 1 | 47.456 | 
| ELX-EMFIP-AGOG-TS-175 | 48W00000CLDRW-16 | E_CLDRW-1 | CLDRW-1 | Generation | 48W00000CLDRW-16 | E_CLDRW-1 | CLDRW-1 | 2020-01-01 | 1 | 3.096 |