Skip to content
Snippets Groups Projects
Commit 1c9365a0 authored by James Graham's avatar James Graham
Browse files

Add CsvConnector as first of internal data sources

parent abe15699
Branches
Tags
1 merge request!60Merge dev pre-hackday
# Generated by Django 2.0.8 on 2018-10-29 13:34
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('applications', '0005_one_to_one_group'),
]
operations = [
migrations.AlterField(
model_name='application',
name='url',
field=models.URLField(blank=True),
),
]
...@@ -10,6 +10,8 @@ MAX_LENGTH_NAME = 63 ...@@ -10,6 +10,8 @@ MAX_LENGTH_NAME = 63
MAX_LENGTH_API_KEY = 127 MAX_LENGTH_API_KEY = 127
MAX_LENGTH_PATH = 255
class BaseAppDataModel(models.Model): class BaseAppDataModel(models.Model):
#: Friendly name of this application #: Friendly name of this application
...@@ -20,7 +22,7 @@ class BaseAppDataModel(models.Model): ...@@ -20,7 +22,7 @@ class BaseAppDataModel(models.Model):
description = models.TextField(blank=True, null=False) description = models.TextField(blank=True, null=False)
#: Address at which the API may be accessed #: Address at which the API may be accessed
url = models.URLField(blank=False, null=False) url = models.URLField(blank=True, null=False)
#: Do users require explicit permission to use this data source / application? #: Do users require explicit permission to use this data source / application?
access_control = models.BooleanField(default=False, access_control = models.BooleanField(default=False,
......
import typing
from .base import DataSetConnector
class DummyResponse:
def __init__(self,
text: str,
status_code: int,
content_type: str):
self.text = text
self.status_code = status_code
self.headers = {
'content-type': content_type,
}
class CsvConnector(DataSetConnector):
"""
Data connector for retrieving data from CSV files.
"""
def get_metadata(self,
params: typing.Optional[typing.Mapping[str, str]] = None):
raise NotImplementedError('CSV does not provide metadata')
def get_data(self,
params: typing.Optional[typing.Mapping[str, str]] = None):
raise NotImplementedError('CSV does not provide metadata')
def get_response(self,
params: typing.Optional[typing.Mapping[str, str]] = None):
"""
Return a dummy response from a CSV file.
:param params: Optional query parameter filters - ignored
:return: Requested data
"""
with open(self.location, 'r') as f:
return DummyResponse(f.read(), 200, 'text/plain')
# Generated by Django 2.0.8 on 2018-10-29 13:20
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('datasources', '0007_datasource_api_key'),
]
operations = [
migrations.AddField(
model_name='datasource',
name='_connector_string',
field=models.CharField(blank=True, max_length=255),
),
]
# Generated by Django 2.0.8 on 2018-10-29 13:34
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('datasources', '0008_datasource__connector_string'),
]
operations = [
migrations.AlterField(
model_name='datasource',
name='url',
field=models.URLField(blank=True),
),
]
...@@ -7,7 +7,7 @@ from django.db import models ...@@ -7,7 +7,7 @@ from django.db import models
from django.urls import reverse from django.urls import reverse
from datasources.connectors.base import BaseDataConnector from datasources.connectors.base import BaseDataConnector
from core.models import BaseAppDataModel, MAX_LENGTH_API_KEY, MAX_LENGTH_NAME from core.models import BaseAppDataModel, MAX_LENGTH_API_KEY, MAX_LENGTH_NAME, MAX_LENGTH_PATH
class DataSource(BaseAppDataModel): class DataSource(BaseAppDataModel):
...@@ -30,6 +30,10 @@ class DataSource(BaseAppDataModel): ...@@ -30,6 +30,10 @@ class DataSource(BaseAppDataModel):
related_name='datasources', related_name='datasources',
blank=False, null=False) blank=False, null=False)
#: Information required to initialise the connector for this data source
_connector_string = models.CharField(max_length=MAX_LENGTH_PATH,
blank=True, null=False)
#: Name of plugin which allows interaction with this data source #: Name of plugin which allows interaction with this data source
plugin_name = models.CharField(max_length=MAX_LENGTH_NAME, plugin_name = models.CharField(max_length=MAX_LENGTH_NAME,
blank=False, null=False) blank=False, null=False)
...@@ -42,6 +46,12 @@ class DataSource(BaseAppDataModel): ...@@ -42,6 +46,12 @@ class DataSource(BaseAppDataModel):
super().__init__(*args, **kwargs) super().__init__(*args, **kwargs)
self._data_connector = None self._data_connector = None
@property
def connector_string(self):
if self._connector_string:
return self._connector_string
return self.url
@property @property
def data_connector(self) -> BaseDataConnector: def data_connector(self) -> BaseDataConnector:
""" """
...@@ -62,9 +72,9 @@ class DataSource(BaseAppDataModel): ...@@ -62,9 +72,9 @@ class DataSource(BaseAppDataModel):
raise KeyError('Data source plugin not found') from e raise KeyError('Data source plugin not found') from e
if self.api_key: if self.api_key:
self._data_connector = plugin(self.url, self.api_key) self._data_connector = plugin(self.connector_string, self.api_key)
else: else:
self._data_connector = plugin(self.url) self._data_connector = plugin(self.connector_string)
return self._data_connector return self._data_connector
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment