python-service-builder 1.3.0__tar.gz → 2.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (18) hide show
  1. {python_service_builder-1.3.0/python_service_builder.egg-info → python_service_builder-2.1.0}/PKG-INFO +36 -18
  2. {python_service_builder-1.3.0 → python_service_builder-2.1.0}/README.md +35 -17
  3. {python_service_builder-1.3.0 → python_service_builder-2.1.0}/pyproject.toml +1 -1
  4. {python_service_builder-1.3.0 → python_service_builder-2.1.0/python_service_builder.egg-info}/PKG-INFO +36 -18
  5. {python_service_builder-1.3.0 → python_service_builder-2.1.0}/python_service_builder.egg-info/SOURCES.txt +3 -2
  6. {python_service_builder-1.3.0 → python_service_builder-2.1.0}/service_framework/__init__.py +10 -17
  7. {python_service_builder-1.3.0 → python_service_builder-2.1.0}/service_framework/service_builder.py +1 -1
  8. python_service_builder-1.3.0/service_framework/list_services.py → python_service_builder-2.1.0/service_framework/service_finder.py +32 -41
  9. python_service_builder-2.1.0/service_framework/services.py +406 -0
  10. {python_service_builder-1.3.0 → python_service_builder-2.1.0}/service_framework/services_test.py +1 -1
  11. python_service_builder-2.1.0/service_framework/update_services.py +47 -0
  12. python_service_builder-1.3.0/service_framework/services.py +0 -949
  13. {python_service_builder-1.3.0 → python_service_builder-2.1.0}/LICENSE +0 -0
  14. {python_service_builder-1.3.0 → python_service_builder-2.1.0}/python_service_builder.egg-info/dependency_links.txt +0 -0
  15. {python_service_builder-1.3.0 → python_service_builder-2.1.0}/python_service_builder.egg-info/requires.txt +0 -0
  16. {python_service_builder-1.3.0 → python_service_builder-2.1.0}/python_service_builder.egg-info/top_level.txt +0 -0
  17. {python_service_builder-1.3.0 → python_service_builder-2.1.0}/service_framework/__init_test.py +0 -0
  18. {python_service_builder-1.3.0 → python_service_builder-2.1.0}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: python-service-builder
3
- Version: 1.3.0
3
+ Version: 2.1.0
4
4
  Summary: Helper library for easier creation of Google services.
5
5
  Author-email: David Harcombe <david.harcombe@gmail.com>
6
6
  License-Expression: Apache-2.0
@@ -49,10 +49,12 @@ ready for use.
49
49
 
50
50
  `service_builder.build_service()` needs two mandatory pieces of information:
51
51
 
52
- | Parameter | Description |
53
- | :-: | - |
54
- | key | The credentials to use to authenticate the user to the service it has to create |
55
- | service | The Google API endpoint it is trying to connect to. |
52
+ | Parameter | Type | Description |
53
+ | :-: | - | - |
54
+ | key | str | The credentials to use to authenticate the user to the service it has to create. |
55
+ | service | Service | The Google API endpoint it is trying to connect to. |
56
+ | api_key | _See below_ | _Optional_ An API key for those services which require an API key in addition to credentials. |
57
+ | extra_scopes | List[str] | _Optional_ Extra OAuth scopes needed. |
56
58
 
57
59
  ### `key`
58
60
 
@@ -60,7 +62,7 @@ These can be supplied in one of 4 ways.
60
62
 
61
63
  1. A valid `google.oauth2.Credentials` object, created and passed to the
62
64
  service builder.
63
- 1. An `str` which is the name of a local file containing the `json`
65
+ 1. A `str` which is the name of a local file containing the `json`
64
66
  representation of an OAuth credentials object.
65
67
  1. A `Mapping` object which is a `json` keyfile `dict`
66
68
  2. An `OAuthKey` object from this package, which is a `dataclass` object
@@ -69,11 +71,36 @@ These can be supplied in one of 4 ways.
69
71
  ### `service`
70
72
 
71
73
  This is an Enum in the `service_framework.service` module, which defines
72
- the Google service you're planning to connect to. All of these services are
73
- dynamically built, but their names match the Google-defined name.
74
+ the Google service you're planning to connect to. All the standard Google
75
+ services are included (as of the date listed in the `Services.py` file).
74
76
 
75
- ### Example
77
+ If a
78
+ new service has been added but this library has yet to be updated, you can
79
+ request it by using either `Service('<UNLISTED SERVICE>')` or
80
+ `Service.from_value('<UNLISTED SERVICE>')`. This will cause the library to
81
+ attempt to fetch the service's definition from Google and will create an
82
+ entry in the enum for this new service.
76
83
 
84
+ ### Examples
85
+
86
+ #### 1. Using `Credentials`
87
+ ```
88
+ from service_framework.services import Service
89
+ from service_framework import service_builder
90
+ from google.oauth2 import credentials as oauth
91
+
92
+ credentials = oauth.Credentials(
93
+ access_token="<YOUR ACCESS TOKEN>",
94
+ refresh_token="<YOUR REFRESH TOKEN>",
95
+ token_uri="https://oauth2.googleapis.com/token",
96
+ client_id="<YOUR CLIENT ID>",
97
+ client_secret="<YOUR CLIENT SECRET>"
98
+ )
99
+
100
+ service = service_builder.build_service(service=Service.CHAT, key=credentials)
101
+ ```
102
+
103
+ #### 2. Using an `OAuthKey`
77
104
  ```
78
105
  from service_framework.services import Service
79
106
  from service_framework import service_builder
@@ -93,12 +120,3 @@ Here, we are creating the key as an `OAuthKey` object as we have clearly got the
93
120
  tokens and client_[id|secret] from elsewhere. Creating the service is then as
94
121
  simple as invoking the `service_builder.build_service` method which will return
95
122
  you a service you can use.
96
-
97
- ### Other parameters
98
-
99
- `service_builder.build_service()` can also take 2 other optional parameters.
100
-
101
- | Parameter | Description |
102
- | :-: | - |
103
- | api_key | Some APIs require an API key as well as the OAuth credentials |
104
- | extra_scopes | Any extra OAUth scopes required for the operation |
@@ -18,10 +18,12 @@ ready for use.
18
18
 
19
19
  `service_builder.build_service()` needs two mandatory pieces of information:
20
20
 
21
- | Parameter | Description |
22
- | :-: | - |
23
- | key | The credentials to use to authenticate the user to the service it has to create |
24
- | service | The Google API endpoint it is trying to connect to. |
21
+ | Parameter | Type | Description |
22
+ | :-: | - | - |
23
+ | key | str | The credentials to use to authenticate the user to the service it has to create. |
24
+ | service | Service | The Google API endpoint it is trying to connect to. |
25
+ | api_key | _See below_ | _Optional_ An API key for those services which require an API key in addition to credentials. |
26
+ | extra_scopes | List[str] | _Optional_ Extra OAuth scopes needed. |
25
27
 
26
28
  ### `key`
27
29
 
@@ -29,7 +31,7 @@ These can be supplied in one of 4 ways.
29
31
 
30
32
  1. A valid `google.oauth2.Credentials` object, created and passed to the
31
33
  service builder.
32
- 1. An `str` which is the name of a local file containing the `json`
34
+ 1. A `str` which is the name of a local file containing the `json`
33
35
  representation of an OAuth credentials object.
34
36
  1. A `Mapping` object which is a `json` keyfile `dict`
35
37
  2. An `OAuthKey` object from this package, which is a `dataclass` object
@@ -38,11 +40,36 @@ These can be supplied in one of 4 ways.
38
40
  ### `service`
39
41
 
40
42
  This is an Enum in the `service_framework.service` module, which defines
41
- the Google service you're planning to connect to. All of these services are
42
- dynamically built, but their names match the Google-defined name.
43
+ the Google service you're planning to connect to. All the standard Google
44
+ services are included (as of the date listed in the `Services.py` file).
43
45
 
44
- ### Example
46
+ If a
47
+ new service has been added but this library has yet to be updated, you can
48
+ request it by using either `Service('<UNLISTED SERVICE>')` or
49
+ `Service.from_value('<UNLISTED SERVICE>')`. This will cause the library to
50
+ attempt to fetch the service's definition from Google and will create an
51
+ entry in the enum for this new service.
45
52
 
53
+ ### Examples
54
+
55
+ #### 1. Using `Credentials`
56
+ ```
57
+ from service_framework.services import Service
58
+ from service_framework import service_builder
59
+ from google.oauth2 import credentials as oauth
60
+
61
+ credentials = oauth.Credentials(
62
+ access_token="<YOUR ACCESS TOKEN>",
63
+ refresh_token="<YOUR REFRESH TOKEN>",
64
+ token_uri="https://oauth2.googleapis.com/token",
65
+ client_id="<YOUR CLIENT ID>",
66
+ client_secret="<YOUR CLIENT SECRET>"
67
+ )
68
+
69
+ service = service_builder.build_service(service=Service.CHAT, key=credentials)
70
+ ```
71
+
72
+ #### 2. Using an `OAuthKey`
46
73
  ```
47
74
  from service_framework.services import Service
48
75
  from service_framework import service_builder
@@ -62,12 +89,3 @@ Here, we are creating the key as an `OAuthKey` object as we have clearly got the
62
89
  tokens and client_[id|secret] from elsewhere. Creating the service is then as
63
90
  simple as invoking the `service_builder.build_service` method which will return
64
91
  you a service you can use.
65
-
66
- ### Other parameters
67
-
68
- `service_builder.build_service()` can also take 2 other optional parameters.
69
-
70
- | Parameter | Description |
71
- | :-: | - |
72
- | api_key | Some APIs require an API key as well as the OAuth credentials |
73
- | extra_scopes | Any extra OAUth scopes required for the operation |
@@ -4,7 +4,7 @@ build-backend = 'setuptools.build_meta'
4
4
 
5
5
  [project]
6
6
  name = "python-service-builder"
7
- version = "1.3.0"
7
+ version = "2.1.0"
8
8
  authors = [{ name = "David Harcombe", email = "david.harcombe@gmail.com" }]
9
9
  description = "Helper library for easier creation of Google services."
10
10
  readme = "README.md"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: python-service-builder
3
- Version: 1.3.0
3
+ Version: 2.1.0
4
4
  Summary: Helper library for easier creation of Google services.
5
5
  Author-email: David Harcombe <david.harcombe@gmail.com>
6
6
  License-Expression: Apache-2.0
@@ -49,10 +49,12 @@ ready for use.
49
49
 
50
50
  `service_builder.build_service()` needs two mandatory pieces of information:
51
51
 
52
- | Parameter | Description |
53
- | :-: | - |
54
- | key | The credentials to use to authenticate the user to the service it has to create |
55
- | service | The Google API endpoint it is trying to connect to. |
52
+ | Parameter | Type | Description |
53
+ | :-: | - | - |
54
+ | key | str | The credentials to use to authenticate the user to the service it has to create. |
55
+ | service | Service | The Google API endpoint it is trying to connect to. |
56
+ | api_key | _See below_ | _Optional_ An API key for those services which require an API key in addition to credentials. |
57
+ | extra_scopes | List[str] | _Optional_ Extra OAuth scopes needed. |
56
58
 
57
59
  ### `key`
58
60
 
@@ -60,7 +62,7 @@ These can be supplied in one of 4 ways.
60
62
 
61
63
  1. A valid `google.oauth2.Credentials` object, created and passed to the
62
64
  service builder.
63
- 1. An `str` which is the name of a local file containing the `json`
65
+ 1. A `str` which is the name of a local file containing the `json`
64
66
  representation of an OAuth credentials object.
65
67
  1. A `Mapping` object which is a `json` keyfile `dict`
66
68
  2. An `OAuthKey` object from this package, which is a `dataclass` object
@@ -69,11 +71,36 @@ These can be supplied in one of 4 ways.
69
71
  ### `service`
70
72
 
71
73
  This is an Enum in the `service_framework.service` module, which defines
72
- the Google service you're planning to connect to. All of these services are
73
- dynamically built, but their names match the Google-defined name.
74
+ the Google service you're planning to connect to. All the standard Google
75
+ services are included (as of the date listed in the `Services.py` file).
74
76
 
75
- ### Example
77
+ If a
78
+ new service has been added but this library has yet to be updated, you can
79
+ request it by using either `Service('<UNLISTED SERVICE>')` or
80
+ `Service.from_value('<UNLISTED SERVICE>')`. This will cause the library to
81
+ attempt to fetch the service's definition from Google and will create an
82
+ entry in the enum for this new service.
76
83
 
84
+ ### Examples
85
+
86
+ #### 1. Using `Credentials`
87
+ ```
88
+ from service_framework.services import Service
89
+ from service_framework import service_builder
90
+ from google.oauth2 import credentials as oauth
91
+
92
+ credentials = oauth.Credentials(
93
+ access_token="<YOUR ACCESS TOKEN>",
94
+ refresh_token="<YOUR REFRESH TOKEN>",
95
+ token_uri="https://oauth2.googleapis.com/token",
96
+ client_id="<YOUR CLIENT ID>",
97
+ client_secret="<YOUR CLIENT SECRET>"
98
+ )
99
+
100
+ service = service_builder.build_service(service=Service.CHAT, key=credentials)
101
+ ```
102
+
103
+ #### 2. Using an `OAuthKey`
77
104
  ```
78
105
  from service_framework.services import Service
79
106
  from service_framework import service_builder
@@ -93,12 +120,3 @@ Here, we are creating the key as an `OAuthKey` object as we have clearly got the
93
120
  tokens and client_[id|secret] from elsewhere. Creating the service is then as
94
121
  simple as invoking the `service_builder.build_service` method which will return
95
122
  you a service you can use.
96
-
97
- ### Other parameters
98
-
99
- `service_builder.build_service()` can also take 2 other optional parameters.
100
-
101
- | Parameter | Description |
102
- | :-: | - |
103
- | api_key | Some APIs require an API key as well as the OAuth credentials |
104
- | extra_scopes | Any extra OAUth scopes required for the operation |
@@ -8,7 +8,8 @@ python_service_builder.egg-info/requires.txt
8
8
  python_service_builder.egg-info/top_level.txt
9
9
  service_framework/__init__.py
10
10
  service_framework/__init_test.py
11
- service_framework/list_services.py
12
11
  service_framework/service_builder.py
12
+ service_framework/service_finder.py
13
13
  service_framework/services.py
14
- service_framework/services_test.py
14
+ service_framework/services_test.py
15
+ service_framework/update_services.py
@@ -12,27 +12,11 @@
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
14
  import dataclasses
15
- from typing import Any, Callable, Mapping
15
+ from typing import Any, Mapping
16
16
 
17
17
  import dataclasses_json
18
18
 
19
19
 
20
- def lazy_property(f: Callable):
21
- """Decorator that makes a property lazy-evaluated.
22
-
23
- Args:
24
- f: the function to convert to a lazy property.
25
- """
26
- attr_name = '_lazy_' + f.__name__
27
-
28
- @property
29
- def _lazy_property(self) -> Any:
30
- if not hasattr(self, attr_name):
31
- setattr(self, attr_name, f(self))
32
- return getattr(self, attr_name)
33
- return _lazy_property
34
-
35
-
36
20
  def metadata(base: Mapping[str, Any], **custom) -> Mapping[str, Any]:
37
21
  """Merges properties into the metadata and returns the merged result.
38
22
 
@@ -113,3 +97,12 @@ def camel_field(default: Any = None,
113
97
  """
114
98
  return field(default=default, default_factory=default_factory,
115
99
  letter_case=dataclasses_json.LetterCase.CAMEL, **kwargs)
100
+
101
+
102
+ @dataclasses_json.dataclass_json
103
+ @dataclasses.dataclass
104
+ class ServiceDefinition(object):
105
+ """Defines a Google Service for the builder."""
106
+ service_name: str = camel_field()
107
+ version: str = camel_field()
108
+ discovery_service_url: str = camel_field()
@@ -36,7 +36,7 @@ class OAuthKey(object):
36
36
 
37
37
  NOTE: This is by no means the entire key; just the fields neccessary for OAuth.
38
38
  """
39
- access_token: Optional[str] = snake_field(field_name='token')
39
+ access_token: Optional[str] = snake_field(field_name='ken')
40
40
  refresh_token: Optional[str] = snake_field()
41
41
  token_uri: Optional[str] = snake_field()
42
42
  client_id: Optional[str] = snake_field()
@@ -16,42 +16,46 @@ import json
16
16
  import urllib.parse
17
17
  import urllib.request
18
18
  from collections import namedtuple
19
- from contextlib import closing, suppress
20
- from pprint import pprint
19
+ from contextlib import closing
21
20
  from typing import Mapping
22
21
  from urllib.request import urlopen
23
22
 
24
- import aenum as enum
25
- from absl import app
23
+ from service_framework import ServiceDefinition
26
24
 
27
- from service_framework.services import ServiceDefinition
28
25
 
29
- """ _summary_
30
- """
26
+ class ServiceFinder(object):
27
+ """ServiceFinder
28
+ """
29
+ def __call__(cls, value, *args, **kwargs) -> ServiceDefinition:
30
+ """What to do when the `ServiceFinder` is invoked
31
31
 
32
+ Usage:
33
+ ```
34
+ finder = ServiceFinder()
35
+ finder('CHAT')
36
+ ```
32
37
 
33
- class ServiceFinder(enum.EnumMeta):
34
- def __call__(cls, value, *args, **kwargs):
35
- api = ServiceLister().find(name=value.lower())
36
- if api:
37
- (service_name, version) = api[0]
38
- definition = ServiceDefinition(
39
- service_name=service_name,
40
- version=version,
41
- discovery_service_url=(
42
- f'https://{service_name}.googleapis.com/$discovery/rest'
43
- f'?version={version}'))
44
- return definition
38
+ Args:
39
+ value (str): the name of the service to find
45
40
 
46
- else:
47
- raise Exception(f'No service found for {value}')
41
+ Raises:
42
+ Exception: No valid Google service of this name exists
43
+
44
+ Returns:
45
+ ServiceDefinition: the service definition
46
+ """
47
+ if api := ServiceFinder.find(name=value.lower()):
48
+ return api[value.upper()]
48
49
 
50
+ else:
51
+ raise Exception(f'No Google service found with the name {value.upper()}')
49
52
 
50
- class ServiceLister(object):
51
- def find_all(self) -> Mapping[str, str]:
52
- return self.find(None)
53
+ @classmethod
54
+ def find_all(cls) -> Mapping[str, ServiceDefinition]:
55
+ return cls.find(None)
53
56
 
54
- def find(self, name: str) -> Mapping[str, str]:
57
+ @classmethod
58
+ def find(cls, name: str) -> Mapping[str, ServiceDefinition]:
55
59
  Components = namedtuple(
56
60
  typename='Components',
57
61
  field_names=['scheme', 'netloc', 'url', 'path', 'query', 'fragment']
@@ -59,8 +63,7 @@ class ServiceLister(object):
59
63
 
60
64
  apis = {}
61
65
 
62
- parameters = {#'fields': 'items.name,items.version',
63
- 'preferred': 'true'}
66
+ parameters = {'preferred': 'true'}
64
67
  if name:
65
68
  parameters |= {'name': name}
66
69
 
@@ -80,19 +83,7 @@ class ServiceLister(object):
80
83
  api_list = json.loads(_api_list.read())
81
84
  if items := api_list.get('items', None):
82
85
  for api in items:
83
- apis[api['name'].upper()] = (api['name'], api['version'], api['discoveryRestUrl'])
86
+ apis[api['name'].upper()] = ServiceDefinition(
87
+ api['name'], api['version'], api['discoveryRestUrl'])
84
88
 
85
89
  return apis
86
-
87
-
88
- def main(unused) -> None:
89
- del unused
90
-
91
- # apis = ServiceLister().find(name='CHAT'.lower())
92
- apis = ServiceLister().find_all()
93
- pprint(apis, indent=2)
94
-
95
-
96
- if __name__ == '__main__':
97
- with suppress(SystemExit):
98
- app.run(main)