api/catalog: better catalog source names
M test/test_api.py +7 -7
@@ 390,15 390,15 @@ 2020-01-03 00:00:00+00:00    3.0
     catalog = api.catalog()
     catalog2 = mapi.catalog()
     assert catalog == {
-        ('db://localhost:5433/postgres', 'ns-test-mapi'): [('api-1', 'primary')]
+        ('postgres@ns-test-mapi', 'ns-test-mapi'): [('api-1', 'primary')]
     }
     assert catalog2 == {
-        ('db://localhost:5433/postgres', 'ns-test-mapi'): [('api-1', 'primary')],
-        ('db://localhost:5433/postgres', 'ns-test-mapi-2'): [('api-2', 'primary')]
+        ('postgres@ns-test-mapi', 'ns-test-mapi'): [('api-1', 'primary')],
+        ('postgres@ns-test-mapi-2', 'ns-test-mapi-2'): [('api-2', 'primary')]
     }
     catalog3 = mapi.catalog(allsources=False)
     assert catalog3 == {
-        ('db://localhost:5433/postgres', 'ns-test-mapi'): [('api-1', 'primary')]
+        ('postgres@ns-test-mapi', 'ns-test-mapi'): [('api-1', 'primary')]
     }
 
     mapi.update_metadata('api-1', {'descr': 'for the mapi test'})

          
@@ 442,7 442,7 @@ 2020-01-03 00:00:00+00:00    3.0
         mapi.delete('api-3')
     cat = mapi.catalog()
     assert cat == {
-        ('db://localhost:5433/postgres', 'ns-test-mapi-2'): [
+        ('postgres@ns-test-mapi-2', 'ns-test-mapi-2'): [
             ('api-2', 'primary'),
             ('api-3', 'primary')]
     }

          
@@ 500,11 500,11 @@ def test_local_formula_remote_series(map
     )
 
     cat = mapi.catalog(allsources=True)
-    s1 = cat[('db://localhost:5433/postgres', 'ns-test-local')]
+    s1 = cat[('postgres@ns-test-local', 'ns-test-local')]
 
     assert ('local-series', 'primary') in s1
 
-    s2 = list(cat[('db://localhost:5433/postgres', 'ns-test-remote')])
+    s2 = list(cat[('postgres@ns-test-remote', 'ns-test-remote')])
     assert ['remote-series', 'primary'] in s2
 
     mapi.register_formula(

          
M test/test_client.py +6 -6
@@ 161,8 161,8 @@ 2018-01-01 02:00:00+00:00    2.0
 
     client.update('test2', series_in, 'Babar')
     series = client.catalog()
-    assert ['test1', 'primary'] in series[('db://localhost:5433/postgres', 'tsh')]
-    assert ['test2', 'primary'] in series[('db://localhost:5433/postgres', 'tsh')]
+    assert ['test1', 'primary'] in series[('postgres', 'tsh')]
+    assert ['test2', 'primary'] in series[('postgres', 'tsh')]
 
     client.replace('test2', genserie(utcdt(2020, 1, 1), 'D', 3), 'Babar')
     series = client.get('test2')

          
@@ 768,16 768,16 @@ def test_multisources(client, engine):
 
     cat = client.catalog()
     assert cat == {
-        ('db://localhost:5433/postgres', 'other'): [
+        ('postgres@other', 'other'): [
             ['test-other', 'primary']
         ],
-        ('db://localhost:5433/postgres', 'tsh'): [
+        ('postgres', 'tsh'): [
             ['test-mainsource', 'primary'],
         ]
     }
     cat = client.catalog(allsources=False)
-    assert ('db://localhost:5433/postgres', 'tsh') in cat
-    assert ('db://localhost:5433/postgres', 'other') not in cat
+    assert ('postgres', 'tsh') in cat
+    assert ('postgres@other', 'other') not in cat
 
 
 # groups

          
M test/test_http.py +7 -7
@@ 164,7 164,7 @@ def test_base(http):
     res = http.get('/series/catalog')
     assert res.status_code == 200
     assert res.json == {
-        'db://localhost:5433/postgres!tsh': [
+        'postgres': [
             ['test-naive', 'primary'],
             ['test', 'primary']
         ]

          
@@ 445,7 445,7 @@ def test_rename(http):
     assert res.status_code == 204
     res = http.get('/series/catalog')
     assert res.json == {
-        'db://localhost:5433/postgres!tsh': [
+        'postgres': [
             ['test-naive', 'primary'],
             ['test2', 'primary']
         ]

          
@@ 759,10 759,10 @@ def test_multisource(http, engine):
     res = http.get('/series/catalog')
     assert res.status_code == 200
     assert res.json == {
-        'db://localhost:5433/postgres!other': [
+        'postgres@other': [
             ['test-other-source', 'primary']
         ],
-        'db://localhost:5433/postgres!tsh': [
+        'postgres': [
             ['test-naive', 'primary'],
             ['test2', 'primary'],
             ['test3', 'primary'],

          
@@ 777,8 777,8 @@ def test_multisource(http, engine):
         'allsources': False
     })
     assert res.status_code == 200
-    assert 'db://localhost:5433/postgres!tsh' in res.json
-    assert 'db://localhost:5433/postgres!other' not in res.json
+    assert 'postgres' in res.json
+    assert 'postgres@other' not in res.json
 
 
 def test_group(http):

          
@@ 846,7 846,7 @@ def test_group(http):
 
     res = http.get('/group/catalog')
     assert res.json == {
-        'db://localhost:5433/postgres!tsh': [['test_group', 'primary']]
+        'postgres': [['test_group', 'primary']]
     }
 
     res = http.get('/group/metadata', {'name': 'test_group'})

          
M tshistory/api.py +9 -4
@@ 71,6 71,13 @@ class mainsource:
             f'sources={self.othersources or nil})'
         )
 
+    def _instancename(self):
+        parsed = urlparse(self.uri)
+        if self.tsh.namespace == 'tsh':
+            return f'{parsed.path[1:]}'
+        else:
+            return f'{parsed.path[1:]}@{self.tsh.namespace}'
+
     def __init__(self,
                  uri: str,
                  namespace: str='tsh',

          
@@ 415,8 422,7 @@ class mainsource:
         If `allsources` is False, only the main source is listed.
 
         """
-        parsed = urlparse(self.uri)
-        instancename = f'db://{parsed.netloc.split("@")[-1]}{parsed.path}'
+        instancename = self._instancename()
         cat = defaultdict(list)
         for name, kind in self.tsh.list_series(self.engine).items():
             cat[(instancename, self.namespace)].append((name, kind))

          
@@ 699,8 705,7 @@ class mainsource:
         source to a list of (name, kind) pair.
 
         """
-        parsed = urlparse(self.uri)
-        instancename = f'db://{parsed.netloc.split("@")[-1]}{parsed.path}'
+        instancename = self._instancename()
         cat = defaultdict(list)
         for name, kind in self.tsh.list_groups(self.engine).items():
             cat[(instancename, self.namespace)].append((name, kind))

          
M tshistory/http/client.py +4 -2
@@ 397,9 397,10 @@ class Client:
         res = self.session.get(f'{self.uri}/series/catalog', params={
             'allsources': allsources
         })
+        tuplify = lambda x: (x, 'tsh') if '@' not in x else (x, x.split('@')[1])
         if res.status_code == 200:
             return {
-                tuple(k.split('!')): v
+                tuplify(k): v
                 for k, v in res.json().items()
             }
 

          
@@ 567,8 568,9 @@ class Client:
             'allsources': allsources
         })
         if res.status_code == 200:
+            tuplify = lambda x: (x, 'tsh') if '@' not in x else (x, x.split('@')[1])
             return {
-                tuple(k.split('!')): [(a, b) for a, b in v]
+                tuplify(k): [(a, b) for a, b in v]
                 for k, v in res.json().items()
             }
 

          
M tshistory/http/server.py +2 -2
@@ 698,7 698,7 @@ class httpapi:
             def get(self):
                 args = catalog.parse_args()
                 cat = {
-                    f'{uri}!{ns}': series
+                    f'{uri}': series
                     for (uri, ns), series in tsa.catalog(allsources=args.allsources).items()
                 }
                 return cat

          
@@ 837,7 837,7 @@ class httpapi:
             @onerror
             def get(self):
                 cat = {
-                    f'{uri}!{ns}': series
+                    f'{uri}': series
                     for (uri, ns), series in tsa.group_catalog().items()
                 }
                 return cat