Skip to content
This repository was archived by the owner on Sep 17, 2025. It is now read-only.

Commit 5331d74

Browse files
zeakosongy23
authored andcommitted
Tags refactoring (#248)
1 parent 24d41ed commit 5331d74

13 files changed

Lines changed: 201 additions & 168 deletions

File tree

.gitignore

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ develop-eggs
1919
lib
2020
lib64
2121
__pycache__
22-
venv/
22+
venv*/
2323

2424
# Installer logs
2525
pip-log.txt

opencensus/tags/__init__.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,3 +11,10 @@
1111
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1212
# See the License for the specific language governing permissions and
1313
# limitations under the License.
14+
15+
from opencensus.tags.tag import Tag
16+
from opencensus.tags.tag_key import TagKey
17+
from opencensus.tags.tag_value import TagValue
18+
from opencensus.tags.tag_map import TagMap
19+
20+
__all__ = ['Tag', 'TagKey', 'TagValue', 'TagMap']

opencensus/tags/propagation/binary_serializer.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -47,12 +47,12 @@ def to_byte_array(self, tag_context):
4747
encoded_bytes = b''
4848
encoded_bytes += _VarintBytes(VERSION_ID)
4949
total_chars = 0
50-
for tag in tag_context.tags:
51-
for tag_key, tag_value in tag.items():
52-
total_chars += len(tag_key)
53-
total_chars += len(tag_value)
54-
encoded_bytes = self._encode_tag(
55-
tag_key, tag_value, encoded_bytes)
50+
for tag in tag_context:
51+
tag_key, tag_value = tag
52+
total_chars += len(tag_key)
53+
total_chars += len(tag_value)
54+
encoded_bytes = self._encode_tag(
55+
tag_key, tag_value, encoded_bytes)
5656
if total_chars <= TAG_MAP_SERIALIZED_SIZE_LIMIT:
5757
return encoded_bytes
5858
else: # pragma: NO COVER

opencensus/tags/tag.py

Lines changed: 8 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -12,30 +12,19 @@
1212
# See the License for the specific language governing permissions and
1313
# limitations under the License.
1414

15-
from opencensus.tags import tag_key
16-
from opencensus.tags import tag_value
15+
from collections import namedtuple
1716

17+
Tag_ = namedtuple('Tag', ['key', 'value'])
1818

19-
class Tag(object):
20-
""" A tag, in the format [KEY]:[VALUE].
2119

22-
:type key: :class: '~opencensus.tags.tag_key.TagKey'
20+
class Tag(Tag_):
21+
"""A tag, in the format [KEY]:[VALUE].
22+
23+
:type key: '~opencensus.tags.tag_key.TagKey'
2324
:param key: Key in the tag
2425
25-
:type value: :class: 'opencensus.tags.tag_value.TagValue'
26+
:type value: '~opencensus.tags.tag_key.TagValue'
2627
:param value: Value of the key in the tag.
2728
2829
"""
29-
def __init__(self, key, value):
30-
self._key = tag_key.TagKey(key)
31-
self._value = tag_value.TagValue(value)
32-
33-
@property
34-
def key(self):
35-
"""The key of the current tag"""
36-
return self._key
37-
38-
@property
39-
def value(self):
40-
"""The value of the key in the current tag"""
41-
return self._value
30+
pass

opencensus/tags/tag_key.py

Lines changed: 13 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -12,36 +12,23 @@
1212
# See the License for the specific language governing permissions and
1313
# limitations under the License.
1414

15+
from opencensus.tags.validation import is_valid_tag_name
1516

16-
class TagKey(object):
17-
""" A tag key with a property name
17+
_TAG_NAME_ERROR = \
18+
'tag name must not be empty,' \
19+
'no longer than 255 characters and of ascii values between 32 - 126'
1820

19-
:type name: str
20-
:param name: The name of the key
2121

22-
"""
23-
def __init__(self, name):
24-
self._name = name
22+
class TagKey(str):
23+
"""A tag key with a property name"""
2524

26-
@property
27-
def name(self):
28-
"""The name of the current key"""
29-
return self._name
30-
31-
def is_valid_name(self, name):
32-
"""Checks if the name of the key is valid
25+
def __new__(cls, name):
26+
"""Create and return a new tag key
3327
3428
:type name: str
35-
:param name: name to check
36-
37-
:rtype: bool
38-
:returns: True if it valid, else returns False
29+
:param name: The name of the key
30+
:return: TagKey
3931
"""
40-
if (len(name) > 0) and (len(name) <= 255):
41-
if (all(ord(char) < 126 for char in name) and
42-
all(ord(char) > 32 for char in name)):
43-
return True
44-
else:
45-
return False
46-
else:
47-
return False
32+
if not is_valid_tag_name(name):
33+
raise ValueError(_TAG_NAME_ERROR)
34+
return super(TagKey, cls).__new__(cls, name)

opencensus/tags/tag_map.py

Lines changed: 32 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,11 @@
1212
# See the License for the specific language governing permissions and
1313
# limitations under the License.
1414

15+
from collections import OrderedDict
16+
17+
from opencensus.tags.tag_key import TagKey
18+
from opencensus.tags.tag_value import TagValue
19+
1520

1621
class TagMap(object):
1722
""" A tag map is a map of tags from key to value
@@ -20,21 +25,12 @@ class TagMap(object):
2025
:param tags: a list of tags
2126
2227
"""
23-
def __init__(self, tags=None):
24-
self._map = {}
25-
if tags is not None:
26-
self.tags = tags
27-
for tag in self.tags:
28-
for tag_key, tag_value in tag.items():
29-
self._map[tag_key] = tag_value
3028

31-
else:
32-
self._map = {}
29+
def __init__(self, tags=None):
30+
self.map = OrderedDict(tags if tags else [])
3331

34-
@property
35-
def map(self):
36-
"""The current map of tags"""
37-
return self._map
32+
def __iter__(self):
33+
return self.map.items().__iter__()
3834

3935
def insert(self, key, value):
4036
"""Inserts a key and value in the map if the map does not already
@@ -48,43 +44,50 @@ def insert(self, key, value):
4844
the value to insert into the tag map
4945
5046
"""
51-
if key not in self._map:
52-
self._map[key] = value
47+
if key in self.map:
48+
return
49+
50+
try:
51+
tag_key = TagKey(key)
52+
tag_val = TagValue(value)
53+
self.map[tag_key] = tag_val
54+
except ValueError:
55+
raise
5356

5457
def delete(self, key):
55-
""" Deletes a tag from the map if the key is in the map
58+
"""Deletes a tag from the map if the key is in the map
5659
57-
:type key: str
60+
:type key: :class: '~opencensus.tags.tag_key.TagKey'
5861
:param key: A string representing a possible tag key
5962
6063
:returns: the value of the key in the dictionary if it is in there,
6164
or None if it is not.
6265
"""
63-
self._map.pop(key, None)
66+
self.map.pop(key, None)
6467

6568
def update(self, key, value):
66-
""" Updates the map by updating the value of a key
69+
"""Updates the map by updating the value of a key
6770
6871
:type key: :class: '~opencensus.tags.tag_key.TagKey'
6972
:param key: A tag key to be updated
7073
71-
:type value: str
74+
:type value: :class: '~opencensus.tags.tag_value.TagValue'
7275
:param value: The value to update the key to in the map
7376
7477
"""
75-
if key in self._map:
76-
self._map[key] = value
78+
if key in self.map:
79+
self.map[key] = value
7780

7881
def tag_key_exists(self, key):
79-
""" Checking if the tag key exists in the map
82+
"""Checking if the tag key exists in the map
8083
81-
:type key: str
84+
:type key: '~opencensus.tags.tag_key.TagKey'
8285
:param key: A string to check to see if that is a key in the map
8386
8487
:returns: True if the key is in map, False is it is not
8588
8689
"""
87-
return key in self._map
90+
return key in self.map
8891

8992
def get_value(self, key):
9093
""" Gets the value of the key passed in if the key exists in the map
@@ -95,8 +98,7 @@ def get_value(self, key):
9598
:returns: A KeyError if the value is None, else returns the value
9699
97100
"""
98-
value = self._map.get(key, None)
99-
if value is None:
100-
raise KeyError('Key is not in map.')
101-
102-
return value
101+
try:
102+
return self.map[key]
103+
except KeyError:
104+
raise KeyError('key is not in map')

opencensus/tags/tag_value.py

Lines changed: 13 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -12,37 +12,23 @@
1212
# See the License for the specific language governing permissions and
1313
# limitations under the License.
1414

15+
from opencensus.tags.validation import is_valid_tag_value
1516

16-
class TagValue(object):
17-
""" The value of a tag
17+
_TAG_VALUE_ERROR = \
18+
'tag value must not be longer than 255 characters ' \
19+
'and of ascii values between 32 - 126'
1820

19-
:type value: str
20-
:param value: A string representing the value of a key in a tag
2121

22-
"""
23-
def __init__(self, value):
24-
self._value = value
22+
class TagValue(str):
23+
"""The value of a tag"""
2524

26-
@property
27-
def value(self):
28-
"""The current value"""
29-
return self._value
30-
31-
def is_valid_value(self, value):
32-
""" Checks if the value if valid
25+
def __new__(cls, value):
26+
"""Create and return a new tag value
3327
3428
:type value: str
35-
:param value: the value to be checked
36-
37-
:rtype: bool
38-
:returns: True if valid, if not, False.
39-
29+
:param value: A string representing the value of a key in a tag
30+
:return: TagValue
4031
"""
41-
if len(value) <= 255:
42-
if (all(ord(char) < 126 for char in value) and
43-
all(ord(char) > 32 for char in value)):
44-
return True
45-
else:
46-
return False
47-
else:
48-
return False
32+
if not is_valid_tag_value(value):
33+
raise ValueError(_TAG_VALUE_ERROR)
34+
return super(TagValue, cls).__new__(cls, value)

opencensus/tags/validation.py

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
# Copyright 2018, OpenCensus Authors
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
16+
def is_legal_chars(value):
17+
return all(32 <= ord(char) <= 126 for char in value)
18+
19+
20+
def is_valid_tag_name(name):
21+
"""Checks if the name of a tag key is valid
22+
23+
:type name: str
24+
:param name: name to check
25+
26+
:rtype: bool
27+
:returns: True if it valid, else returns False
28+
"""
29+
return is_legal_chars(name) if 0 < len(name) <= 255 else False
30+
31+
32+
def is_valid_tag_value(value):
33+
"""Checks if the value is valid
34+
35+
:type value: str
36+
:param value: the value to be checked
37+
38+
:rtype: bool
39+
:returns: True if valid, if not, False.
40+
41+
"""
42+
return is_legal_chars(value) if len(value) <= 255 else False

tests/unit/tags/propagation/test_binary_serializer.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414

1515
import unittest
1616

17+
from opencensus.tags import Tag, TagKey, TagValue
1718
from opencensus.tags.propagation import binary_serializer
1819

1920

@@ -43,12 +44,11 @@ def test_from_byte_array(self):
4344

4445
def test_to_byte_array(self):
4546
from opencensus.tags.tag_map import TagMap
46-
from collections import OrderedDict
4747

48-
tag_map = OrderedDict(
49-
[('key1', 'val1'), ('key2', 'val2'),
50-
('key3', 'val3'), ('key4', 'val4')])
51-
tags = [tag_map]
48+
tags = [Tag(TagKey('key1'), TagValue('val1')),
49+
Tag(TagKey('key2'), TagValue('val2')),
50+
Tag(TagKey('key3'), TagValue('val3')),
51+
Tag(TagKey('key4'), TagValue('val4'))]
5252
tag_context = TagMap(tags=tags)
5353
propagator = binary_serializer.BinarySerializer()
5454
binary = propagator.to_byte_array(tag_context)

tests/unit/tags/test_tag.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,15 +13,15 @@
1313
# limitations under the License.
1414

1515
import unittest
16-
from opencensus.tags import tag as tag_module
16+
from opencensus.tags import Tag, TagKey, TagValue
1717

1818

1919
class TestTag(unittest.TestCase):
2020

2121
def test_constructor(self):
2222
key = 'key1'
2323
value = 'value1'
24-
tag = tag_module.Tag(key=key, value=value)
24+
tag = Tag(key=TagKey(key), value=TagValue(value))
2525

26-
self.assertEqual(tag.key.name, key)
27-
self.assertEqual(tag.value.value, value)
26+
self.assertEqual(tag.key, key)
27+
self.assertEqual(tag.value, value)

0 commit comments

Comments
 (0)