Skip to content

Commit 96098b8

Browse files
authored
[Core] Create generic azure-core package: corehttp (#32191)
This adds a new package called `corehttp` into the "sdk/core" directory. This provides the building blocks used when generating Python SDKs. Signed-off-by: Paul Van Eck <[email protected]>
1 parent 0f8f710 commit 96098b8

File tree

111 files changed

+14469
-3
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

111 files changed

+14469
-3
lines changed

.vscode/cspell.json

+3-2
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@
5555
"sdk/core/azure-core-tracing-opencensus/**",
5656
"sdk/core/azure-core-tracing-opentelemetry/**",
5757
"sdk/core/azure-servicemanagement-legacy/**",
58+
"sdk/core/corehttp/**",
5859
"sdk/digitaltwins/azure-digitaltwins-core/**",
5960
"sdk/eventhub/azure-eventhub-checkpointstoretable/**",
6061
"sdk/eventhub/azure-eventhub-checkpointstoreblob-aio/**",
@@ -99,7 +100,7 @@
99100
"sdk/translation/azure-ai-translation-text/tests/test_transliteration.py",
100101
"sdk/translation/azure-ai-translation-text/tests/test_break_sentence_async.py",
101102
"sdk/translation/azure-ai-translation-text/tests/test_translation_async.py",
102-
"sdk/translation/azure-ai-translation-text/tests/test_transliteration_async.py",
103+
"sdk/translation/azure-ai-translation-text/tests/test_transliteration_async.py",
103104
"sdk/translation/test-resources.json",
104105
"eng/**/*.json",
105106
"eng/*.txt",
@@ -502,7 +503,7 @@
502503
"words": [
503504
"wammsa"
504505
]
505-
},
506+
},
506507
{
507508
"filename": "sdk/tables/azure-data-tables/tests/**/*.py",
508509
"words": [

eng/.docsettings.yml

+3
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,7 @@ known_content_issues:
103103
- ['sdk/appconfiguration/azure-appconfiguration/swagger/README.md', '#4554']
104104
- ['sdk/attestation/azure-security-attestation/swagger/README.md', '#4554']
105105
- ['sdk/core/azure-core/tests/testserver_tests/coretestserver/README.rst', '#4554']
106+
- ['sdk/core/corehttp/tests/testserver_tests/coretestserver/README.rst', '#4554']
106107
- ['sdk/media/azure-media-analytics-edge/README.md', '#4554']
107108
- ['sdk/remoterendering/azure-mixedreality-remoterendering/README.md', '#4554']
108109
- ['sdk/modelsrepository/azure-iot-modelsrepository/README.md', '#4554']
@@ -115,6 +116,8 @@ known_content_issues:
115116
- ['sdk/core/azure-common/README.rst', 'common']
116117
- ['sdk/core/azure-core/README.md', 'common']
117118
- ['sdk/core/azure-core/samples/README.md', 'common']
119+
- ['sdk/core/corehttp/README.md', 'common']
120+
- ['sdk/core/corehttp/samples/README.md', 'common']
118121
- ['sdk/search/azure-search-documents/README.md', 'common']
119122
- ['sdk/storage/azure-storage-blob/samples/README.md', 'common']
120123
- ['sdk/storage/azure-storage-file-datalake/samples/README.md', 'common']

sdk/core/ci.yml

+4-1
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ extends:
3535
template: ../../eng/pipelines/templates/stages/archetype-sdk-client.yml
3636
parameters:
3737
ServiceDirectory: core
38+
BuildTargetingString: '*'
3839
ValidateFormatting: true
3940
Artifacts:
4041
- name: azure-core
@@ -49,4 +50,6 @@ extends:
4950
safeName: azurecommon
5051
skipPublishDocMs: true
5152
- name: azure-core-experimental
52-
safeName: azurecoreexperimental
53+
safeName: azurecoreexperimental
54+
- name: corehttp
55+
safeName: corehttp

sdk/core/corehttp/CHANGELOG.md

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# Release History
2+
3+
## 1.0.0b1 (2023-10-18)
4+
5+
* Initial Release

sdk/core/corehttp/LICENSE

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
Copyright (c) Microsoft Corporation.
2+
3+
MIT License
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

sdk/core/corehttp/MANIFEST.in

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
recursive-include tests *.py
2+
include *.md
3+
include LICENSE
4+
include corehttp/__init__.py
5+
recursive-include samples *.py *.md
6+
include corehttp/py.typed

sdk/core/corehttp/README.md

+29
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
2+
# Core HTTP shared client library for Python
3+
4+
`corehttp` provides shared exceptions and modules for Python SDK client libraries.
5+
6+
## Getting started
7+
8+
Typically, you will not need to install `corehttp`, as it will be installed when you install one of the client libraries using it.
9+
10+
## Contributing
11+
12+
This project welcomes contributions and suggestions. Most contributions require
13+
you to agree to a Contributor License Agreement (CLA) declaring that you have
14+
the right to, and actually do, grant us the rights to use your contribution.
15+
For details, visit [https://cla.microsoft.com](https://cla.microsoft.com).
16+
17+
When you submit a pull request, a CLA-bot will automatically determine whether
18+
you need to provide a CLA and decorate the PR appropriately (e.g., label,
19+
comment). Simply follow the instructions provided by the bot. You will only
20+
need to do this once across all repos using our CLA.
21+
22+
This project has adopted the
23+
[Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/).
24+
For more information, see the
25+
[Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/)
26+
or contact [[email protected]](mailto:[email protected]) with any
27+
additional questions or comments.
28+
29+
+35
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
# --------------------------------------------------------------------------
2+
#
3+
# Copyright (c) Microsoft Corporation. All rights reserved.
4+
#
5+
# The MIT License (MIT)
6+
#
7+
# Permission is hereby granted, free of charge, to any person obtaining a copy
8+
# of this software and associated documentation files (the ""Software""), to
9+
# deal in the Software without restriction, including without limitation the
10+
# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
11+
# sell copies of the Software, and to permit persons to whom the Software is
12+
# furnished to do so, subject to the following conditions:
13+
#
14+
# The above copyright notice and this permission notice shall be included in
15+
# all copies or substantial portions of the Software.
16+
#
17+
# THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22+
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
23+
# IN THE SOFTWARE.
24+
#
25+
# --------------------------------------------------------------------------
26+
27+
from ._version import VERSION
28+
29+
__version__ = VERSION
30+
31+
from ._match_conditions import MatchConditions
32+
33+
__all__ = [
34+
"MatchConditions",
35+
]
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
# --------------------------------------------------------------------------
2+
#
3+
# Copyright (c) Microsoft Corporation. All rights reserved.
4+
#
5+
# The MIT License (MIT)
6+
#
7+
# Permission is hereby granted, free of charge, to any person obtaining a copy
8+
# of this software and associated documentation files (the ""Software""), to
9+
# deal in the Software without restriction, including without limitation the
10+
# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
11+
# sell copies of the Software, and to permit persons to whom the Software is
12+
# furnished to do so, subject to the following conditions:
13+
#
14+
# The above copyright notice and this permission notice shall be included in
15+
# all copies or substantial portions of the Software.
16+
#
17+
# THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22+
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
23+
# IN THE SOFTWARE.
24+
#
25+
# --------------------------------------------------------------------------
26+
27+
from enum import Enum
28+
29+
30+
class MatchConditions(Enum):
31+
"""An enum to describe match conditions."""
32+
33+
Unconditionally = 1
34+
"""Matches any condition"""
35+
36+
IfNotModified = 2
37+
"""If the target object is not modified. Usually it maps to etag=<specific etag>"""
38+
39+
IfModified = 3
40+
"""Only if the target object is modified. Usually it maps to etag!=<specific etag>"""
41+
42+
IfPresent = 4
43+
"""If the target object exists. Usually it maps to etag='*'"""
44+
45+
IfMissing = 5
46+
"""If the target object does not exist. Usually it maps to etag!='*'"""
+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
# coding=utf-8
2+
# --------------------------------------------------------------------------
3+
# Copyright (c) Microsoft Corporation. All rights reserved.
4+
# Licensed under the MIT License. See License.txt in the project root for
5+
# license information.
6+
#
7+
# Code generated by Microsoft (R) AutoRest Code Generator.
8+
# Changes may cause incorrect behavior and will be lost if the code is
9+
# regenerated.
10+
# --------------------------------------------------------------------------
11+
12+
VERSION = "1.0.0b1"
+155
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,155 @@
1+
# -------------------------------------------------------------------------
2+
# Copyright (c) Microsoft Corporation. All rights reserved.
3+
# Licensed under the MIT License. See LICENSE.txt in the project root for
4+
# license information.
5+
# -------------------------------------------------------------------------
6+
from __future__ import annotations
7+
from collections import namedtuple
8+
from types import TracebackType
9+
from typing import Any, NamedTuple, Optional, AsyncContextManager, Type
10+
from typing_extensions import Protocol, runtime_checkable
11+
12+
13+
class AccessToken(NamedTuple):
14+
"""Represents an OAuth access token."""
15+
16+
token: str
17+
expires_on: int
18+
19+
20+
AccessToken.token.__doc__ = """The token string."""
21+
AccessToken.expires_on.__doc__ = """The token's expiration time in Unix time."""
22+
23+
24+
@runtime_checkable
25+
class TokenCredential(Protocol):
26+
"""Protocol for classes able to provide OAuth tokens."""
27+
28+
def get_token(self, *scopes: str, claims: Optional[str] = None, **kwargs: Any) -> AccessToken:
29+
"""Request an access token for `scopes`.
30+
31+
:param str scopes: The type of access needed.
32+
33+
:keyword str claims: Additional claims required in the token, such as those returned in a resource
34+
provider's claims challenge following an authorization failure.
35+
36+
37+
:rtype: AccessToken
38+
:return: An AccessToken instance containing the token string and its expiration time in Unix time.
39+
"""
40+
...
41+
42+
43+
ServiceNamedKey = namedtuple("ServiceNamedKey", ["name", "key"])
44+
45+
__all__ = [
46+
"AccessToken",
47+
"ServiceKeyCredential",
48+
"ServiceNamedKeyCredential",
49+
"TokenCredential",
50+
"AsyncTokenCredential",
51+
]
52+
53+
54+
class ServiceKeyCredential:
55+
"""Credential type used for authenticating to a service.
56+
It provides the ability to update the key without creating a new client.
57+
58+
:param str key: The key used to authenticate to a service
59+
:raises: TypeError
60+
"""
61+
62+
def __init__(self, key: str) -> None:
63+
if not isinstance(key, str):
64+
raise TypeError("key must be a string.")
65+
self._key = key
66+
67+
@property
68+
def key(self) -> str:
69+
"""The value of the configured key.
70+
71+
:rtype: str
72+
:return: The value of the configured key.
73+
"""
74+
return self._key
75+
76+
def update(self, key: str) -> None:
77+
"""Update the key.
78+
79+
This can be used when you've regenerated your service key and want
80+
to update long-lived clients.
81+
82+
:param str key: The key used to authenticate to a service
83+
:raises: ValueError or TypeError
84+
"""
85+
if not key:
86+
raise ValueError("The key used for updating can not be None or empty")
87+
if not isinstance(key, str):
88+
raise TypeError("The key used for updating must be a string.")
89+
self._key = key
90+
91+
92+
class ServiceNamedKeyCredential:
93+
"""Credential type used for working with any service needing a named key that follows patterns
94+
established by the other credential types.
95+
96+
:param str name: The name of the credential used to authenticate to a service.
97+
:param str key: The key used to authenticate to a service.
98+
:raises: TypeError
99+
"""
100+
101+
def __init__(self, name: str, key: str) -> None:
102+
if not isinstance(name, str) or not isinstance(key, str):
103+
raise TypeError("Both name and key must be strings.")
104+
self._credential = ServiceNamedKey(name, key)
105+
106+
@property
107+
def named_key(self) -> ServiceNamedKey:
108+
"""The value of the configured name.
109+
110+
:rtype: ServiceNamedKey
111+
:return: The value of the configured name.
112+
"""
113+
return self._credential
114+
115+
def update(self, name: str, key: str) -> None:
116+
"""Update the named key credential.
117+
118+
Both name and key must be provided in order to update the named key credential.
119+
Individual attributes cannot be updated.
120+
121+
:param str name: The name of the credential used to authenticate to a service.
122+
:param str key: The key used to authenticate to a service.
123+
"""
124+
if not isinstance(name, str) or not isinstance(key, str):
125+
raise TypeError("Both name and key must be strings.")
126+
self._credential = ServiceNamedKey(name, key)
127+
128+
129+
@runtime_checkable
130+
class AsyncTokenCredential(Protocol, AsyncContextManager["AsyncTokenCredential"]):
131+
"""Protocol for classes able to provide OAuth tokens."""
132+
133+
async def get_token(self, *scopes: str, claims: Optional[str] = None, **kwargs: Any) -> AccessToken:
134+
"""Request an access token for `scopes`.
135+
136+
:param str scopes: The type of access needed.
137+
138+
:keyword str claims: Additional claims required in the token, such as those returned in a resource
139+
provider's claims challenge following an authorization failure.
140+
141+
:rtype: AccessToken
142+
:return: An AccessToken instance containing the token string and its expiration time in Unix time.
143+
"""
144+
...
145+
146+
async def close(self) -> None:
147+
pass
148+
149+
async def __aexit__(
150+
self,
151+
exc_type: Optional[Type[BaseException]] = None,
152+
exc_value: Optional[BaseException] = None,
153+
traceback: Optional[TracebackType] = None,
154+
) -> None:
155+
pass

0 commit comments

Comments
 (0)