Compare commits
22 Commits
python-0.1
...
0.24.1-ser
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d7fad6d8d3 | ||
|
|
188767e15a | ||
|
|
59a8cafc74 | ||
|
|
4ef6083344 | ||
|
|
b50637d36f | ||
|
|
c653914694 | ||
|
|
921ef46eb8 | ||
|
|
4c46effc9b | ||
|
|
8bb1943dca | ||
|
|
b4075818be | ||
|
|
a7d322bcd8 | ||
|
|
4c5183e9bd | ||
|
|
a432b9af7d | ||
|
|
b8a69356d4 | ||
|
|
d1b1a6b1e5 | ||
|
|
63dbfa27b5 | ||
|
|
b7ea87cc11 | ||
|
|
6654b69212 | ||
|
|
d95155af71 | ||
|
|
160409c8c0 | ||
|
|
8b031a3016 | ||
|
|
607c8e82c9 |
12
NEWS.md
12
NEWS.md
@@ -1,3 +1,15 @@
|
||||
May 16th, 2017
|
||||
=============
|
||||
* Version `0.24.1` of the server
|
||||
* Fixed an interface mismatch between DS API and OBS backend, when returning no data. See #366
|
||||
|
||||
May 9th, 2017
|
||||
=============
|
||||
* Version `0.17.0` of the client and version `0.24.0` of the server
|
||||
* Fixed some missing return values documented but not present.
|
||||
* `OBS_GetAvailableGeometries` now returns `geom_type`, `geom_extra` and `geom_tags` in addition to existing values.
|
||||
* `OBS_GetAvailableTimespans` now returns `timespan_type`, `timespan_extra`, `timespan_tags` in addition to existing values.
|
||||
|
||||
March 28th, 2017
|
||||
================
|
||||
|
||||
|
||||
80
README.md
80
README.md
@@ -23,26 +23,12 @@ Steps to deploy a new Data Services API version :
|
||||
|
||||
### Local install instructions
|
||||
|
||||
- install data services geocoder extension
|
||||
|
||||
```
|
||||
git clone https://github.com/CartoDB/data-services.git
|
||||
cd data-services/geocoder/extension
|
||||
sudo make install
|
||||
```
|
||||
|
||||
- install observatory extension
|
||||
|
||||
```
|
||||
git clone https://github.com/CartoDB/observatory-extension.git
|
||||
cd observatory
|
||||
sudo make install
|
||||
```
|
||||
|
||||
- install server and client extensions
|
||||
|
||||
```
|
||||
# in dataservices-api repo root path:
|
||||
# in your workspace root path
|
||||
git clone https://github.com/CartoDB/dataservices-api.git
|
||||
cd dataservices-api
|
||||
cd client && sudo make install
|
||||
cd -
|
||||
cd server/extension && sudo make install
|
||||
@@ -55,16 +41,64 @@ Steps to deploy a new Data Services API version :
|
||||
cd server/lib/python/cartodb_services && pip install -r requirements.txt && sudo pip install . --upgrade
|
||||
```
|
||||
|
||||
- install extensions in user database
|
||||
- Create a database to hold all the server part and a user for it
|
||||
|
||||
```sql
|
||||
CREATE DATABASE dataservices_db ENCODING = 'UTF8' LC_COLLATE = 'en_US.UTF-8' LC_CTYPE = 'en_US.UTF-8';
|
||||
CREATE USER dataservices_user;
|
||||
```
|
||||
|
||||
- Install needed extensions in `dataservices_db` database
|
||||
|
||||
```
|
||||
create extension cdb_geocoder;
|
||||
create extension plproxy;
|
||||
create extension observatory;
|
||||
create extension cdb_dataservices_server;
|
||||
create extension cdb_dataservices_client;
|
||||
psql -U postgres -d dataservices_db -c "BEGIN;CREATE EXTENSION IF NOT EXISTS plproxy; COMMIT" -e
|
||||
psql -U postgres -d dataservices_db -c "BEGIN;CREATE EXTENSION IF NOT EXISTS cdb_dataservices_server; COMMIT" -e
|
||||
```
|
||||
|
||||
- [optional] install internal geocoder
|
||||
- Make the extension available in postgres
|
||||
```
|
||||
git clone https://github.com/CartoDB/data-services.git
|
||||
cd data-services/geocoder/extension
|
||||
sudo make install
|
||||
```
|
||||
|
||||
- Make sure you have `wget` installed because is needed for the next step.
|
||||
|
||||
- Go to `geocoder` folder and execute the `geocoder_dowload_dumps` script to download the internal geocoder data.
|
||||
|
||||
- Once the data is downloaded, execute this command:
|
||||
```bash
|
||||
geocoder_restore_dump postgres dataservices_db {DOWNLOADED_DUMPS_FOLDER}/*.sql
|
||||
```
|
||||
|
||||
- Now we have to make available the extension to be installed by postgres. Follow [this](https://github.com/CartoDB/data-services/tree/master/geocoder/extension) instructions.
|
||||
|
||||
- Now install the extension with:
|
||||
```
|
||||
psql -U postgres -d dataservices_db -c "BEGIN;CREATE EXTENSION IF NOT EXISTS cdb_geocoder; COMMIT" -e
|
||||
```
|
||||
|
||||
- [optional] install data observatory extension
|
||||
- Make the extension available in postgresql to be installed
|
||||
```
|
||||
git clone https://github.com/CartoDB/observatory-extension.git
|
||||
cd observatory
|
||||
sudo make install
|
||||
```
|
||||
- This extension needs data, dumps are not available so we're going to use the test fixtures to make it work. Execute:
|
||||
```
|
||||
psql -U postgres -d dataservices_db -f src/pg/test/fixtures/load_fixtures.sql
|
||||
```
|
||||
- Give permission to execute and select to the `dataservices_user` user:
|
||||
```
|
||||
psql -U postgres -d dataservices_db -c "BEGIN;CREATE EXTENSION IF NOT EXISTS observatoru; COMMIT" -e
|
||||
psql -U postgres -d dataservices_db -c "BEGIN;GRANT SELECT ON ALL TABLES IN SCHEMA cdb_observatory TO dataservices_user; COMMIT" -e
|
||||
psql -U postgres -d dataservices_db -c "BEGIN;GRANT EXECUTE ON ALL FUNCTIONS IN SCHEMA cdb_observatory TO dataservices_user; COMMIT" -e
|
||||
psql -U postgres -d dataservices_db -c "BEGIN;GRANT SELECT ON ALL TABLES IN SCHEMA observatory TO dataservices_user; COMMIT" -e
|
||||
psql -U postgres -d dataservices_db -c "BEGIN;GRANT EXECUTE ON ALL FUNCTIONS IN SCHEMA observatory TO dataservices_user; COMMIT" -e
|
||||
```
|
||||
|
||||
### Server configuration
|
||||
|
||||
Configuration for the different services must be stored in the server database using `CDB_Conf_SetConf()`.
|
||||
|
||||
14
client/cdb_dataservices_client--0.16.0--0.17.0.sql
Normal file
14
client/cdb_dataservices_client--0.16.0--0.17.0.sql
Normal file
@@ -0,0 +1,14 @@
|
||||
--DO NOT MODIFY THIS FILE, IT IS GENERATED AUTOMATICALLY FROM SOURCES
|
||||
-- Complain if script is sourced in psql, rather than via CREATE EXTENSION
|
||||
\echo Use "ALTER EXTENSION cdb_dataservices_client UPDATE TO '0.17.0'" to load this file. \quit
|
||||
|
||||
-- Make sure we have a sane search path to create/update the extension
|
||||
SET search_path = "$user",cartodb,public,cdb_dataservices_client;
|
||||
|
||||
ALTER TYPE cdb_dataservices_client.obs_meta_geometry ADD ATTRIBUTE geom_type text;
|
||||
ALTER TYPE cdb_dataservices_client.obs_meta_geometry ADD ATTRIBUTE geom_extra jsonb;
|
||||
ALTER TYPE cdb_dataservices_client.obs_meta_geometry ADD ATTRIBUTE geom_tags jsonb;
|
||||
|
||||
ALTER TYPE cdb_dataservices_client.obs_meta_timespan ADD ATTRIBUTE timespan_type text;
|
||||
ALTER TYPE cdb_dataservices_client.obs_meta_timespan ADD ATTRIBUTE timespan_extra jsonb;
|
||||
ALTER TYPE cdb_dataservices_client.obs_meta_timespan ADD ATTRIBUTE timespan_tags jsonb;
|
||||
14
client/cdb_dataservices_client--0.17.0--0.16.0.sql
Normal file
14
client/cdb_dataservices_client--0.17.0--0.16.0.sql
Normal file
@@ -0,0 +1,14 @@
|
||||
--DO NOT MODIFY THIS FILE, IT IS GENERATED AUTOMATICALLY FROM SOURCES
|
||||
-- Complain if script is sourced in psql, rather than via CREATE EXTENSION
|
||||
\echo Use "ALTER EXTENSION cdb_dataservices_client UPDATE TO '0.16.0'" to load this file. \quit
|
||||
|
||||
-- Make sure we have a sane search path to create/update the extension
|
||||
SET search_path = "$user",cartodb,public,cdb_dataservices_client;
|
||||
|
||||
ALTER TYPE cdb_dataservices_client.obs_meta_geometry DROP ATTRIBUTE geom_type;
|
||||
ALTER TYPE cdb_dataservices_client.obs_meta_geometry DROP ATTRIBUTE geom_extra;
|
||||
ALTER TYPE cdb_dataservices_client.obs_meta_geometry DROP ATTRIBUTE geom_tags;
|
||||
|
||||
ALTER TYPE cdb_dataservices_client.obs_meta_timespan DROP ATTRIBUTE timespan_type;
|
||||
ALTER TYPE cdb_dataservices_client.obs_meta_timespan DROP ATTRIBUTE timespan_extra;
|
||||
ALTER TYPE cdb_dataservices_client.obs_meta_timespan DROP ATTRIBUTE timespan_tags;
|
||||
4130
client/cdb_dataservices_client--0.17.0.sql
Normal file
4130
client/cdb_dataservices_client--0.17.0.sql
Normal file
File diff suppressed because it is too large
Load Diff
@@ -1,5 +1,5 @@
|
||||
comment = 'CartoDB dataservices client API extension'
|
||||
default_version = '0.16.0'
|
||||
default_version = '0.17.0'
|
||||
requires = 'plproxy, cartodb'
|
||||
superuser = true
|
||||
schema = cdb_dataservices_client
|
||||
|
||||
@@ -15,9 +15,9 @@ CREATE TYPE cdb_dataservices_client.obs_meta_numerator AS (numer_id text, numer_
|
||||
|
||||
CREATE TYPE cdb_dataservices_client.obs_meta_denominator AS (denom_id text, denom_name text, denom_description text, denom_weight text, denom_license text, denom_source text, denom_type text, denom_aggregate text, denom_extra jsonb, denom_tags jsonb, valid_numer boolean, valid_geom boolean, valid_timespan boolean);
|
||||
|
||||
CREATE TYPE cdb_dataservices_client.obs_meta_geometry AS (geom_id text, geom_name text, geom_description text, geom_weight text, geom_aggregate text, geom_license text, geom_source text, valid_numer boolean, valid_denom boolean, valid_timespan boolean, score numeric, numtiles bigint, notnull_percent numeric, numgeoms numeric, percentfill numeric, estnumgeoms numeric, meanmediansize numeric);
|
||||
CREATE TYPE cdb_dataservices_client.obs_meta_geometry AS (geom_id text, geom_name text, geom_description text, geom_weight text, geom_aggregate text, geom_license text, geom_source text, valid_numer boolean, valid_denom boolean, valid_timespan boolean, score numeric, numtiles bigint, notnull_percent numeric, numgeoms numeric, percentfill numeric, estnumgeoms numeric, meanmediansize numeric, geom_type text, geom_extra jsonb, geom_tags jsonb);
|
||||
|
||||
CREATE TYPE cdb_dataservices_client.obs_meta_timespan AS (timespan_id text, timespan_name text, timespan_description text, timespan_weight text, timespan_aggregate text, timespan_license text, timespan_source text, valid_numer boolean, valid_denom boolean, valid_geom boolean);
|
||||
CREATE TYPE cdb_dataservices_client.obs_meta_timespan AS (timespan_id text, timespan_name text, timespan_description text, timespan_weight text, timespan_aggregate text, timespan_license text, timespan_source text, valid_numer boolean, valid_denom boolean, valid_geom boolean, timespan_type text, timespan_extra jsonb, timespan_tags jsonb);
|
||||
|
||||
|
||||
-- For quotas and services configuration
|
||||
|
||||
@@ -83,7 +83,7 @@ The result is a JSON object with the configuration (`period` and `limit` attribu
|
||||
#### Example:
|
||||
|
||||
```
|
||||
SELECT cdb_dataservices_client.cdb_service_get_rate_limit('geocoding');
|
||||
SELECT cdb_dataservices_client.cdb_service_get_rate_limit('geocoder');
|
||||
|
||||
cdb_service_get_rate_limit
|
||||
---------------------------------
|
||||
@@ -108,16 +108,18 @@ This functions doesn't return any value.
|
||||
|
||||
#### Example
|
||||
|
||||
This will configure the geocoding service rate limit for user `myusername`, a non-organization user.
|
||||
This will configure the geocoder service rate limit for user `myusername`, a non-organization user.
|
||||
The limit will be set at 1000 requests per day. Since the user doesn't belong to any organization,
|
||||
`NULL` will be passed to the organization argument; otherwise the name of the user's organization should
|
||||
be provided.
|
||||
|
||||
Note that the name of the geocoding services is `geocoder` and not `geocoding`.
|
||||
|
||||
```
|
||||
SELECT cdb_dataservices_client.cdb_service_set_user_rate_limit(
|
||||
'myusername',
|
||||
NULL,
|
||||
'geocoding',
|
||||
'geocoder',
|
||||
'{"limit":1000,"period":86400}'
|
||||
);
|
||||
|
||||
@@ -140,7 +142,7 @@ This functions doesn't return any value.
|
||||
|
||||
#### Example
|
||||
|
||||
This will configure the geocoding service rate limit for the `myorg` organization.
|
||||
This will configure the geocoder service rate limit for the `myorg` organization.
|
||||
The limit will be set at 100 requests per hour.
|
||||
Note that even we're setting the default configuration for the whole organization,
|
||||
the name of a user of the organization must be provided for technical reasons.
|
||||
@@ -149,7 +151,7 @@ the name of a user of the organization must be provided for technical reasons.
|
||||
SELECT cdb_dataservices_client.cdb_service_set_org_rate_limit(
|
||||
'myorgadmin',
|
||||
'myorg',
|
||||
'geocoding',
|
||||
'geocoder',
|
||||
'{"limit":100,"period":3600}'
|
||||
);
|
||||
|
||||
@@ -172,7 +174,7 @@ This functions doesn't return any value.
|
||||
|
||||
#### Example
|
||||
|
||||
This will configure the default geocoding service rate limit for all users
|
||||
This will configure the default geocoder service rate limit for all users
|
||||
accesing the data-services server.
|
||||
The limit will be set at 10000 requests per month.
|
||||
Note that even we're setting the default configuration for the server,
|
||||
@@ -183,7 +185,7 @@ must be provided for technical reasons.
|
||||
SELECT cdb_dataservices_client.cdb_service_set_server_rate_limit(
|
||||
'myorgadmin',
|
||||
'myorg',
|
||||
'geocoding',
|
||||
'geocoder',
|
||||
'{"limit":10000,"period":108000}'
|
||||
);
|
||||
|
||||
|
||||
100
server/extension/cdb_dataservices_server--0.24.0--0.24.1.sql
Normal file
100
server/extension/cdb_dataservices_server--0.24.0--0.24.1.sql
Normal file
@@ -0,0 +1,100 @@
|
||||
--DO NOT MODIFY THIS FILE, IT IS GENERATED AUTOMATICALLY FROM SOURCES
|
||||
-- Complain if script is sourced in psql, rather than via CREATE EXTENSION
|
||||
\echo Use "ALTER EXTENSION cdb_dataservices_server UPDATE TO '0.24.1'" to load this file. \quit
|
||||
|
||||
|
||||
CREATE OR REPLACE FUNCTION cdb_dataservices_server.OBS_GetData(
|
||||
username TEXT,
|
||||
orgname TEXT,
|
||||
geomvals geomval[],
|
||||
params JSON,
|
||||
merge BOOLEAN DEFAULT True)
|
||||
RETURNS TABLE (
|
||||
id INT,
|
||||
data JSON
|
||||
) AS $$
|
||||
from cartodb_services.metrics import metrics
|
||||
from cartodb_services.metrics import QuotaService
|
||||
from cartodb_services.tools import Logger,LoggerConfig
|
||||
|
||||
plpy.execute("SELECT cdb_dataservices_server._connect_to_redis('{0}')".format(username))
|
||||
redis_conn = GD["redis_connection_{0}".format(username)]['redis_metrics_connection']
|
||||
plpy.execute("SELECT cdb_dataservices_server._get_obs_config({0}, {1})".format(plpy.quote_nullable(username), plpy.quote_nullable(orgname)))
|
||||
user_obs_config = GD["user_obs_config_{0}".format(username)]
|
||||
|
||||
plpy.execute("SELECT cdb_dataservices_server._get_logger_config()")
|
||||
logger_config = GD["logger_config"]
|
||||
logger = Logger(logger_config)
|
||||
quota_service = QuotaService(user_obs_config, redis_conn)
|
||||
if not quota_service.check_user_quota():
|
||||
raise Exception('You have reached the limit of your quota')
|
||||
|
||||
with metrics('obs_getdata', user_obs_config, logger):
|
||||
try:
|
||||
obs_plan = plpy.prepare("SELECT * FROM cdb_dataservices_server._OBS_GetData($1, $2, $3, $4, $5);", ["text", "text", "geomval[]", "json", "boolean"])
|
||||
result = plpy.execute(obs_plan, [username, orgname, geomvals, params, merge])
|
||||
empty_results = len(geomvals) - len(result)
|
||||
if empty_results > 0:
|
||||
quota_service.increment_empty_service_use(empty_results)
|
||||
if result:
|
||||
quota_service.increment_success_service_use(len(result))
|
||||
return result
|
||||
else:
|
||||
return []
|
||||
except BaseException as e:
|
||||
import sys
|
||||
quota_service.increment_failed_service_use(len(geomvals))
|
||||
logger.error('Error trying to OBS_GetData', sys.exc_info(), data={"username": username, "orgname": orgname})
|
||||
raise Exception('Error trying to OBS_GetData')
|
||||
finally:
|
||||
quota_service.increment_total_service_use(len(geomvals))
|
||||
$$ LANGUAGE plpythonu;
|
||||
|
||||
|
||||
CREATE OR REPLACE FUNCTION cdb_dataservices_server.OBS_GetData(
|
||||
username TEXT,
|
||||
orgname TEXT,
|
||||
geomrefs TEXT[],
|
||||
params JSON)
|
||||
RETURNS TABLE (
|
||||
id TEXT,
|
||||
data JSON
|
||||
) AS $$
|
||||
from cartodb_services.metrics import metrics
|
||||
from cartodb_services.metrics import QuotaService
|
||||
from cartodb_services.tools import Logger,LoggerConfig
|
||||
|
||||
plpy.execute("SELECT cdb_dataservices_server._connect_to_redis('{0}')".format(username))
|
||||
redis_conn = GD["redis_connection_{0}".format(username)]['redis_metrics_connection']
|
||||
plpy.execute("SELECT cdb_dataservices_server._get_obs_config({0}, {1})".format(plpy.quote_nullable(username), plpy.quote_nullable(orgname)))
|
||||
user_obs_config = GD["user_obs_config_{0}".format(username)]
|
||||
|
||||
plpy.execute("SELECT cdb_dataservices_server._get_logger_config()")
|
||||
logger_config = GD["logger_config"]
|
||||
logger = Logger(logger_config)
|
||||
quota_service = QuotaService(user_obs_config, redis_conn)
|
||||
if not quota_service.check_user_quota():
|
||||
raise Exception('You have reached the limit of your quota')
|
||||
|
||||
with metrics('obs_getdata', user_obs_config, logger):
|
||||
try:
|
||||
obs_plan = plpy.prepare("SELECT * FROM cdb_dataservices_server._OBS_GetData($1, $2, $3, $4);", ["text", "text", "text[]", "json"])
|
||||
result = plpy.execute(obs_plan, [username, orgname, geomrefs, params])
|
||||
empty_results = len(geomrefs) - len(result)
|
||||
if empty_results > 0:
|
||||
quota_service.increment_empty_service_use(empty_results)
|
||||
if result:
|
||||
quota_service.increment_success_service_use(len(result))
|
||||
return result
|
||||
else:
|
||||
return []
|
||||
except BaseException as e:
|
||||
import sys
|
||||
quota_service.increment_failed_service_use(len(geomrefs))
|
||||
exc_info = sys.exc_info()
|
||||
logger.error('%s, %s, %s' % (exc_info[0], exc_info[1], exc_info[2]))
|
||||
logger.error('Error trying to OBS_GetData', exc_info, data={"username": username, "orgname": orgname})
|
||||
raise Exception('Error trying to OBS_GetData')
|
||||
finally:
|
||||
quota_service.increment_total_service_use(len(geomrefs))
|
||||
$$ LANGUAGE plpythonu;
|
||||
100
server/extension/cdb_dataservices_server--0.24.1--0.24.0.sql
Normal file
100
server/extension/cdb_dataservices_server--0.24.1--0.24.0.sql
Normal file
@@ -0,0 +1,100 @@
|
||||
--DO NOT MODIFY THIS FILE, IT IS GENERATED AUTOMATICALLY FROM SOURCES
|
||||
-- Complain if script is sourced in psql, rather than via CREATE EXTENSION
|
||||
\echo Use "ALTER EXTENSION cdb_dataservices_server UPDATE TO '0.24.0'" to load this file. \quit
|
||||
|
||||
|
||||
CREATE OR REPLACE FUNCTION cdb_dataservices_server.OBS_GetData(
|
||||
username TEXT,
|
||||
orgname TEXT,
|
||||
geomvals geomval[],
|
||||
params JSON,
|
||||
merge BOOLEAN DEFAULT True)
|
||||
RETURNS TABLE (
|
||||
id INT,
|
||||
data JSON
|
||||
) AS $$
|
||||
from cartodb_services.metrics import metrics
|
||||
from cartodb_services.metrics import QuotaService
|
||||
from cartodb_services.tools import Logger,LoggerConfig
|
||||
|
||||
plpy.execute("SELECT cdb_dataservices_server._connect_to_redis('{0}')".format(username))
|
||||
redis_conn = GD["redis_connection_{0}".format(username)]['redis_metrics_connection']
|
||||
plpy.execute("SELECT cdb_dataservices_server._get_obs_config({0}, {1})".format(plpy.quote_nullable(username), plpy.quote_nullable(orgname)))
|
||||
user_obs_config = GD["user_obs_config_{0}".format(username)]
|
||||
|
||||
plpy.execute("SELECT cdb_dataservices_server._get_logger_config()")
|
||||
logger_config = GD["logger_config"]
|
||||
logger = Logger(logger_config)
|
||||
quota_service = QuotaService(user_obs_config, redis_conn)
|
||||
if not quota_service.check_user_quota():
|
||||
raise Exception('You have reached the limit of your quota')
|
||||
|
||||
with metrics('obs_getdata', user_obs_config, logger):
|
||||
try:
|
||||
obs_plan = plpy.prepare("SELECT * FROM cdb_dataservices_server._OBS_GetData($1, $2, $3, $4, $5);", ["text", "text", "geomval[]", "json", "boolean"])
|
||||
result = plpy.execute(obs_plan, [username, orgname, geomvals, params, merge])
|
||||
empty_results = len(geomvals) - len(result)
|
||||
if empty_results > 0:
|
||||
quota_service.increment_empty_service_use(empty_results)
|
||||
if result:
|
||||
quota_service.increment_success_service_use(len(result))
|
||||
return result
|
||||
else:
|
||||
return None
|
||||
except BaseException as e:
|
||||
import sys
|
||||
quota_service.increment_failed_service_use(len(geomvals))
|
||||
logger.error('Error trying to OBS_GetData', sys.exc_info(), data={"username": username, "orgname": orgname})
|
||||
raise Exception('Error trying to OBS_GetData')
|
||||
finally:
|
||||
quota_service.increment_total_service_use(len(geomvals))
|
||||
$$ LANGUAGE plpythonu;
|
||||
|
||||
|
||||
CREATE OR REPLACE FUNCTION cdb_dataservices_server.OBS_GetData(
|
||||
username TEXT,
|
||||
orgname TEXT,
|
||||
geomrefs TEXT[],
|
||||
params JSON)
|
||||
RETURNS TABLE (
|
||||
id TEXT,
|
||||
data JSON
|
||||
) AS $$
|
||||
from cartodb_services.metrics import metrics
|
||||
from cartodb_services.metrics import QuotaService
|
||||
from cartodb_services.tools import Logger,LoggerConfig
|
||||
|
||||
plpy.execute("SELECT cdb_dataservices_server._connect_to_redis('{0}')".format(username))
|
||||
redis_conn = GD["redis_connection_{0}".format(username)]['redis_metrics_connection']
|
||||
plpy.execute("SELECT cdb_dataservices_server._get_obs_config({0}, {1})".format(plpy.quote_nullable(username), plpy.quote_nullable(orgname)))
|
||||
user_obs_config = GD["user_obs_config_{0}".format(username)]
|
||||
|
||||
plpy.execute("SELECT cdb_dataservices_server._get_logger_config()")
|
||||
logger_config = GD["logger_config"]
|
||||
logger = Logger(logger_config)
|
||||
quota_service = QuotaService(user_obs_config, redis_conn)
|
||||
if not quota_service.check_user_quota():
|
||||
raise Exception('You have reached the limit of your quota')
|
||||
|
||||
with metrics('obs_getdata', user_obs_config, logger):
|
||||
try:
|
||||
obs_plan = plpy.prepare("SELECT * FROM cdb_dataservices_server._OBS_GetData($1, $2, $3, $4);", ["text", "text", "text[]", "json"])
|
||||
result = plpy.execute(obs_plan, [username, orgname, geomrefs, params])
|
||||
empty_results = len(geomrefs) - len(result)
|
||||
if empty_results > 0:
|
||||
quota_service.increment_empty_service_use(empty_results)
|
||||
if result:
|
||||
quota_service.increment_success_service_use(len(result))
|
||||
return result
|
||||
else:
|
||||
return None
|
||||
except BaseException as e:
|
||||
import sys
|
||||
quota_service.increment_failed_service_use(len(geomrefs))
|
||||
exc_info = sys.exc_info()
|
||||
logger.error('%s, %s, %s' % (exc_info[0], exc_info[1], exc_info[2]))
|
||||
logger.error('Error trying to OBS_GetData', exc_info, data={"username": username, "orgname": orgname})
|
||||
raise Exception('Error trying to OBS_GetData')
|
||||
finally:
|
||||
quota_service.increment_total_service_use(len(geomrefs))
|
||||
$$ LANGUAGE plpythonu;
|
||||
2977
server/extension/cdb_dataservices_server--0.24.1.sql
Normal file
2977
server/extension/cdb_dataservices_server--0.24.1.sql
Normal file
File diff suppressed because it is too large
Load Diff
@@ -1,5 +1,5 @@
|
||||
comment = 'CartoDB dataservices server extension'
|
||||
default_version = '0.23.0'
|
||||
default_version = '0.24.1'
|
||||
requires = 'plpythonu, plproxy, postgis, cdb_geocoder'
|
||||
superuser = true
|
||||
schema = cdb_dataservices_server
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
--DO NOT MODIFY THIS FILE, IT IS GENERATED AUTOMATICALLY FROM SOURCES
|
||||
-- Complain if script is sourced in psql, rather than via CREATE EXTENSION
|
||||
\echo Use "ALTER EXTENSION cdb_dataservices_server UPDATE TO '0.24.0'" to load this file. \quit
|
||||
|
||||
ALTER TYPE cdb_dataservices_server.obs_meta_geometry ADD ATTRIBUTE geom_type text;
|
||||
ALTER TYPE cdb_dataservices_server.obs_meta_geometry ADD ATTRIBUTE geom_extra jsonb;
|
||||
ALTER TYPE cdb_dataservices_server.obs_meta_geometry ADD ATTRIBUTE geom_tags jsonb;
|
||||
|
||||
ALTER TYPE cdb_dataservices_server.obs_meta_timespan ADD ATTRIBUTE timespan_type text;
|
||||
ALTER TYPE cdb_dataservices_server.obs_meta_timespan ADD ATTRIBUTE timespan_extra jsonb;
|
||||
ALTER TYPE cdb_dataservices_server.obs_meta_timespan ADD ATTRIBUTE timespan_tags jsonb;
|
||||
@@ -0,0 +1,12 @@
|
||||
--DO NOT MODIFY THIS FILE, IT IS GENERATED AUTOMATICALLY FROM SOURCES
|
||||
-- Complain if script is sourced in psql, rather than via CREATE EXTENSION
|
||||
\echo Use "ALTER EXTENSION cdb_dataservices_server UPDATE TO '0.23.0'" to load this file. \quit
|
||||
|
||||
-- HERE goes your code to upgrade/downgrade
|
||||
ALTER TYPE cdb_dataservices_server.obs_meta_geometry DROP ATTRIBUTE geom_type;
|
||||
ALTER TYPE cdb_dataservices_server.obs_meta_geometry DROP ATTRIBUTE geom_extra;
|
||||
ALTER TYPE cdb_dataservices_server.obs_meta_geometry DROP ATTRIBUTE geom_tags;
|
||||
|
||||
ALTER TYPE cdb_dataservices_server.obs_meta_timespan DROP ATTRIBUTE timespan_type;
|
||||
ALTER TYPE cdb_dataservices_server.obs_meta_timespan DROP ATTRIBUTE timespan_extra;
|
||||
ALTER TYPE cdb_dataservices_server.obs_meta_timespan DROP ATTRIBUTE timespan_tags;
|
||||
2977
server/extension/old_versions/cdb_dataservices_server--0.24.0.sql
Normal file
2977
server/extension/old_versions/cdb_dataservices_server--0.24.0.sql
Normal file
File diff suppressed because it is too large
Load Diff
@@ -619,7 +619,7 @@ RETURNS TABLE (
|
||||
quota_service.increment_success_service_use(len(result))
|
||||
return result
|
||||
else:
|
||||
return None
|
||||
return []
|
||||
except BaseException as e:
|
||||
import sys
|
||||
quota_service.increment_failed_service_use(len(geomvals))
|
||||
@@ -678,7 +678,7 @@ RETURNS TABLE (
|
||||
quota_service.increment_success_service_use(len(result))
|
||||
return result
|
||||
else:
|
||||
return None
|
||||
return []
|
||||
except BaseException as e:
|
||||
import sys
|
||||
quota_service.increment_failed_service_use(len(geomrefs))
|
||||
|
||||
@@ -35,7 +35,7 @@ RETURNS SETOF cdb_dataservices_server.obs_meta_denominator AS $$
|
||||
SELECT * FROM cdb_observatory.OBS_GetAvailableDenominators(bounds, filter_tags, numer_id, geom_id, timespan);
|
||||
$$ LANGUAGE plproxy;
|
||||
|
||||
CREATE TYPE cdb_dataservices_server.obs_meta_geometry AS (geom_id text, geom_name text, geom_description text, geom_weight text, geom_aggregate text, geom_license text, geom_source text, valid_numer boolean, valid_denom boolean, valid_timespan boolean, score numeric, numtiles bigint, notnull_percent numeric, numgeoms numeric, percentfill numeric, estnumgeoms numeric, meanmediansize numeric);
|
||||
CREATE TYPE cdb_dataservices_server.obs_meta_geometry AS (geom_id text, geom_name text, geom_description text, geom_weight text, geom_aggregate text, geom_license text, geom_source text, valid_numer boolean, valid_denom boolean, valid_timespan boolean, score numeric, numtiles bigint, notnull_percent numeric, numgeoms numeric, percentfill numeric, estnumgeoms numeric, meanmediansize numeric, geom_type text, geom_extra jsonb, geom_tags jsonb);
|
||||
|
||||
CREATE OR REPLACE FUNCTION cdb_dataservices_server.OBS_GetAvailableGeometries(
|
||||
username TEXT,
|
||||
@@ -50,7 +50,7 @@ RETURNS SETOF cdb_dataservices_server.obs_meta_geometry AS $$
|
||||
SELECT * FROM cdb_observatory.OBS_GetAvailableGeometries(bounds, filter_tags, numer_id, denom_id, timespan);
|
||||
$$ LANGUAGE plproxy;
|
||||
|
||||
CREATE TYPE cdb_dataservices_server.obs_meta_timespan AS (timespan_id text, timespan_name text, timespan_description text, timespan_weight text, timespan_aggregate text, timespan_license text, timespan_source text, valid_numer boolean, valid_denom boolean, valid_geom boolean);
|
||||
CREATE TYPE cdb_dataservices_server.obs_meta_timespan AS (timespan_id text, timespan_name text, timespan_description text, timespan_weight text, timespan_aggregate text, timespan_license text, timespan_source text, valid_numer boolean, valid_denom boolean, valid_geom boolean, timespan_type text, timespan_extra jsonb, timespan_tags jsonb);
|
||||
|
||||
CREATE OR REPLACE FUNCTION cdb_dataservices_server.OBS_GetAvailableTimespans(
|
||||
username TEXT,
|
||||
|
||||
@@ -37,7 +37,7 @@ SELECT cartodb.cdb_conf_setconf('logger_conf', '{"geocoder_log_path": "/dev/null
|
||||
|
||||
(1 row)
|
||||
|
||||
SELECT cartodb.cdb_conf_setconf('data_observatory_conf', '{"connection": {"whitelist": ["ethervoid"], "production": "host=localhost port=5432 dbname=dataservices_db user=geocoder_api", "staging": "host=localhost port=5432 dbname=dataservices_db user=geocoder_api"}, "monthly_quota": 100000}');
|
||||
SELECT cartodb.cdb_conf_setconf('data_observatory_conf', '{"connection": {"whitelist": ["ethervoid"], "production": "host=localhost port=5432 dbname=contrib_regression user=geocoder_api", "staging": "host=localhost port=5432 dbname=dataservices_db user=geocoder_api"}, "monthly_quota": 100000}');
|
||||
cdb_conf_setconf
|
||||
------------------
|
||||
|
||||
|
||||
9
server/extension/test/expected/366_empty_table_test.out
Normal file
9
server/extension/test/expected/366_empty_table_test.out
Normal file
@@ -0,0 +1,9 @@
|
||||
\set ECHO none
|
||||
id | data
|
||||
----+------
|
||||
(0 rows)
|
||||
|
||||
id | data
|
||||
----+------
|
||||
(0 rows)
|
||||
|
||||
@@ -14,7 +14,7 @@ SELECT cartodb.cdb_conf_setconf('redis_metadata_config', '{"redis_host": "localh
|
||||
SELECT cartodb.cdb_conf_setconf('heremaps_conf', '{"geocoder": {"app_id": "dummy_id", "app_code": "dummy_code", "geocoder_cost_per_hit": 1}, "isolines": {"app_id": "dummy_id", "app_code": "dummy_code"}}');
|
||||
SELECT cartodb.cdb_conf_setconf('mapzen_conf', '{"routing": {"api_key": "routing_dummy_api_key", "monthly_quota": 1500000}, "geocoder": {"api_key": "geocoder_dummy_api_key", "monthly_quota": 1500000}, "matrix": {"api_key": "matrix_dummy_api_key", "monthly_quota": 1500000}}');
|
||||
SELECT cartodb.cdb_conf_setconf('logger_conf', '{"geocoder_log_path": "/dev/null"}');
|
||||
SELECT cartodb.cdb_conf_setconf('data_observatory_conf', '{"connection": {"whitelist": ["ethervoid"], "production": "host=localhost port=5432 dbname=dataservices_db user=geocoder_api", "staging": "host=localhost port=5432 dbname=dataservices_db user=geocoder_api"}, "monthly_quota": 100000}');
|
||||
SELECT cartodb.cdb_conf_setconf('data_observatory_conf', '{"connection": {"whitelist": ["ethervoid"], "production": "host=localhost port=5432 dbname=contrib_regression user=geocoder_api", "staging": "host=localhost port=5432 dbname=dataservices_db user=geocoder_api"}, "monthly_quota": 100000}');
|
||||
|
||||
-- Mock the varnish invalidation function
|
||||
-- (used by cdb_geocoder tests)
|
||||
|
||||
65
server/extension/test/sql/366_empty_table_test.sql
Normal file
65
server/extension/test/sql/366_empty_table_test.sql
Normal file
@@ -0,0 +1,65 @@
|
||||
\set ECHO none
|
||||
\set VERBOSITY verbose
|
||||
SET client_min_messages TO error;
|
||||
|
||||
-- Set configuration for a user 'foo'
|
||||
DO $$
|
||||
import json
|
||||
from cartodb_services.config import ServiceConfiguration
|
||||
|
||||
import cartodb_services
|
||||
cartodb_services.init(plpy, GD)
|
||||
|
||||
service_config = ServiceConfiguration('observatory', 'foo', None)
|
||||
service_config.user.set('soft_obs_general_limit', True)
|
||||
service_config.user.set('period_end_date', '20170516')
|
||||
|
||||
$$ LANGUAGE plpythonu;
|
||||
|
||||
|
||||
-- Mock Observatory backend function
|
||||
CREATE SCHEMA cdb_observatory;
|
||||
CREATE OR REPLACE FUNCTION cdb_observatory.OBS_GetData(geomvals geomval[], params JSON, merge BOOLEAN DEFAULT TRUE)
|
||||
RETURNS TABLE (
|
||||
id INT,
|
||||
data JSON
|
||||
) AS $$
|
||||
BEGIN
|
||||
-- this will return an empty set
|
||||
RAISE NOTICE 'Mocked OBS_GetData()';
|
||||
END;
|
||||
$$ LANGUAGE plpgsql;
|
||||
GRANT USAGE ON SCHEMA cdb_observatory TO geocoder_api;
|
||||
GRANT EXECUTE ON ALL FUNCTIONS IN SCHEMA cdb_observatory TO geocoder_api;
|
||||
|
||||
|
||||
-- Test it
|
||||
SELECT * FROM cdb_dataservices_server.OBS_GetData(
|
||||
'foo',
|
||||
NULL,
|
||||
'{"(0103000020E61000000100000005000000010000E0F67F52C096D88AE6B25F4440010000E0238052C0BF6D8A1A8D5D4440010000D0DA7E52C05F03F3CC265D444001000020F47E52C0F2DD78AB5D5F4440010000E0F67F52C096D88AE6B25F4440,1)"}'::public._geomval,
|
||||
'[{"id": 1, "score": 52.7515548093083898758340051256007949661290516400338, "geom_id": "us.census.tiger.census_tract", "denom_id": "us.census.acs.B01003001", "numer_id": "us.census.acs.B03002003", "geom_name": "US Census Tracts", "geom_type": "Geometry", "num_geoms": 2.86483076549783307739486952736, "denom_name": "Total Population", "denom_type": "Numeric", "numer_name": "White Population", "numer_type": "Numeric", "score_rank": 1, "target_area": 0.000307374806576033, "geom_colname": "the_geom", "score_rownum": 1, "target_geoms": null, "denom_colname": "total_pop", "denom_reltype": '
|
||||
'"denominator", "geom_timespan": "2015", "normalization": "prenormalized", "numer_colname": "white_pop", "timespan_rank": 1, "geom_tablename": "obs_87a814e485deabe3b12545a537f693d16ca702c2", "max_score_rank": null, "numer_timespan": "2010 - 2014", "suggested_name": "white_pop_2010_2014", "denom_aggregate": "sum", "denom_tablename": "obs_b393b5b88c6adda634b2071a8005b03c551b609a", "numer_aggregate": "sum", "numer_tablename": "obs_b393b5b88c6adda634b2071a8005b03c551b609a", "timespan_rownum": 1, "geom_description": "Census tracts are small, relatively permanent statistical subdivisions of a county or equivalent entity that are updated by local participants prior to each decennial census as part of the Census Bureau’s Participant Statistical Areas Program. The Census Bureau delineates census tracts in situations where no local participant existed or where state, local, or tribal governments'
|
||||
'declined to participate. The primary purpose of census tracts is to provide a stable set of geographic units for the presentation of statistical data.\r\n\r\nCensus tracts generally have a population size between 1,200 and 8,000 people, with an optimum size of 4,000 people. A census tract usually covers a contiguous area; however, the spatial size of census tracts varies widely depending on the density of settlement. Census tract boundaries are delineated with the intention of being maintained over a long time so that statistical comparisons can be made from census to census. Census tracts occasionally are split due to population growth or merged as a result of substantial population decline.\r\n\r\nCensus tract boundaries generally follow visible and identifiable features. They may follow nonvisible legal boundaries, such as minor civil division (MCD) or incorporated place boundaries'
|
||||
'in some states and situations, to allow for census-tract-to-governmental-unit relationships where the governmental boundaries tend to remain unchanged between censuses. State and county boundaries always are census tract boundaries in the standard census geographic hierarchy. Tribal census tracts are a unique geographic entity defined within federally recognized American Indian reservations and off-reservation trust lands and can cross state and county boundaries. Tribal census tracts may be completely different from the census tracts and block groups defined by state and county (see “Tribal Census Tract”).", "denom_description": "The total number of all people living in a given geographic area. This is a very useful catch-all denominator when calculating rates.", "max_timespan_rank": null, "numer_description": "The number of people identifying as white, non-Hispanic in each'
|
||||
'geography.", "geom_t_description": null, "denom_t_description": null, "numer_t_description": null, "geom_geomref_colname": "geoid", "denom_geomref_colname": "geoid", "numer_geomref_colname": "geoid"}]'::json,
|
||||
true);
|
||||
|
||||
|
||||
|
||||
-- Mock another observatory backend function (overloaded, different params)
|
||||
CREATE OR REPLACE FUNCTION cdb_observatory.OBS_GetData(geomrefs TEXT[], params JSON)
|
||||
RETURNS TABLE (
|
||||
id INT,
|
||||
data JSON
|
||||
) AS $$
|
||||
BEGIN
|
||||
-- this will return an empty set
|
||||
RAISE NOTICE 'Mocked OBS_GetData()';
|
||||
END;
|
||||
$$ LANGUAGE plpgsql;
|
||||
GRANT USAGE ON SCHEMA cdb_observatory TO geocoder_api;
|
||||
GRANT EXECUTE ON ALL FUNCTIONS IN SCHEMA cdb_observatory TO geocoder_api;
|
||||
|
||||
-- Test it
|
||||
SELECT * FROM cdb_dataservices_server.OBS_GetData('foo', NULL, '{bar, baz}'::TEXT[], '[]'::JSON);
|
||||
Reference in New Issue
Block a user