apytizer 0.0.1a0__py3-none-any.whl → 0.0.1b2__py3-none-any.whl
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.
- apytizer/__init__.py +2 -12
- apytizer/adapters/__init__.py +2 -3
- apytizer/adapters/transport_adapter.py +91 -0
- apytizer/apis/__init__.py +6 -0
- apytizer/apis/abstract_api.py +36 -0
- apytizer/apis/web_api.py +460 -0
- apytizer/connections/__init__.py +6 -0
- apytizer/connections/abstract_connection.py +28 -0
- apytizer/connections/http_connection.py +431 -0
- apytizer/decorators/__init__.py +5 -5
- apytizer/decorators/caching.py +60 -9
- apytizer/decorators/chunking.py +105 -0
- apytizer/decorators/connection.py +55 -20
- apytizer/decorators/json.py +70 -12
- apytizer/decorators/pagination.py +50 -32
- apytizer/endpoints/__init__.py +6 -0
- apytizer/endpoints/abstract_endpoint.py +38 -0
- apytizer/endpoints/web_endpoint.py +519 -0
- apytizer/engines/__init__.py +6 -0
- apytizer/engines/abstract_engine.py +45 -0
- apytizer/engines/http_engine.py +171 -0
- apytizer/errors.py +34 -0
- apytizer/factories/__init__.py +5 -0
- apytizer/factories/abstract_factory.py +17 -0
- apytizer/http_methods.py +34 -0
- apytizer/managers/__init__.py +12 -0
- apytizer/managers/abstract_manager.py +80 -0
- apytizer/managers/base_manager.py +116 -0
- apytizer/mappers/__init__.py +6 -0
- apytizer/mappers/abstract_mapper.py +48 -0
- apytizer/mappers/base_mapper.py +78 -0
- apytizer/media_types.py +118 -0
- apytizer/models/__init__.py +6 -0
- apytizer/models/abstract_model.py +119 -0
- apytizer/models/base_model.py +85 -0
- apytizer/protocols.py +38 -0
- apytizer/repositories/__init__.py +6 -0
- apytizer/repositories/abstract_repository.py +81 -0
- apytizer/repositories/managed_repository.py +92 -0
- apytizer/routes/__init__.py +6 -0
- apytizer/routes/abstract_route.py +32 -0
- apytizer/routes/base_route.py +138 -0
- apytizer/sessions/__init__.py +33 -0
- apytizer/sessions/abstract_session.py +63 -0
- apytizer/sessions/requests_session.py +125 -0
- apytizer/states/__init__.py +6 -0
- apytizer/states/abstract_state.py +71 -0
- apytizer/states/local_state.py +99 -0
- apytizer/utils/__init__.py +9 -4
- apytizer/utils/caching.py +39 -0
- apytizer/utils/dictionaries.py +376 -0
- apytizer/utils/errors.py +104 -0
- apytizer/utils/iterables.py +91 -0
- apytizer/utils/objects.py +145 -0
- apytizer/utils/strings.py +69 -0
- apytizer/utils/typing.py +29 -0
- apytizer-0.0.1b2.dist-info/METADATA +41 -0
- apytizer-0.0.1b2.dist-info/RECORD +60 -0
- {apytizer-0.0.1a0.dist-info → apytizer-0.0.1b2.dist-info}/WHEEL +1 -2
- apytizer/abstracts/__init__.py +0 -8
- apytizer/abstracts/api.py +0 -147
- apytizer/abstracts/endpoint.py +0 -177
- apytizer/abstracts/model.py +0 -50
- apytizer/abstracts/session.py +0 -39
- apytizer/adapters/transport.py +0 -40
- apytizer/base/__init__.py +0 -8
- apytizer/base/api.py +0 -510
- apytizer/base/endpoint.py +0 -443
- apytizer/base/model.py +0 -119
- apytizer/utils/generate_key.py +0 -18
- apytizer/utils/merge.py +0 -19
- apytizer-0.0.1a0.dist-info/METADATA +0 -27
- apytizer-0.0.1a0.dist-info/RECORD +0 -25
- apytizer-0.0.1a0.dist-info/top_level.txt +0 -1
- {apytizer-0.0.1a0.dist-info → apytizer-0.0.1b2.dist-info/licenses}/LICENSE +0 -0
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
# src/apytizer/utils/strings.py
|
|
3
|
+
|
|
4
|
+
# Standard Library Imports
|
|
5
|
+
import re
|
|
6
|
+
from typing import Any
|
|
7
|
+
from typing import Iterable
|
|
8
|
+
from typing import List
|
|
9
|
+
|
|
10
|
+
__all__ = [
|
|
11
|
+
"camel_to_snake",
|
|
12
|
+
"iter_format",
|
|
13
|
+
"syntactic_list",
|
|
14
|
+
]
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def camel_to_snake(__s: str, /) -> str:
|
|
18
|
+
"""Convert camelcase string to snakecase.
|
|
19
|
+
|
|
20
|
+
Args:
|
|
21
|
+
__s: Camelcase string to convert.
|
|
22
|
+
|
|
23
|
+
Returns:
|
|
24
|
+
Snakecase string.
|
|
25
|
+
|
|
26
|
+
.. _Based On:
|
|
27
|
+
https://stackoverflow.com/a/1176023.
|
|
28
|
+
|
|
29
|
+
"""
|
|
30
|
+
pattern = re.compile(r"(?<=[a-z0-9])(?=[A-Z][a-z]+)")
|
|
31
|
+
result = pattern.sub("_", __s).lower()
|
|
32
|
+
return result
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
def iter_format(__iter: Iterable[Any], __format: str, /) -> List[str]:
|
|
36
|
+
"""Format each item in an iterable object.
|
|
37
|
+
|
|
38
|
+
Args:
|
|
39
|
+
__iter: Iterable object containing items to format.
|
|
40
|
+
__format: String format to apply to each item.
|
|
41
|
+
|
|
42
|
+
Returns:
|
|
43
|
+
Formatted items.
|
|
44
|
+
|
|
45
|
+
"""
|
|
46
|
+
result = [__format.format(item) for item in __iter]
|
|
47
|
+
return result
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
def syntactic_list(
|
|
51
|
+
__l: List[str], /, conjunction: str, *, oxford: bool = False
|
|
52
|
+
) -> str:
|
|
53
|
+
"""Apply syntax to a list of strings.
|
|
54
|
+
|
|
55
|
+
Args:
|
|
56
|
+
__l: List of strings.
|
|
57
|
+
conjunction: Conjunction with which to join list.
|
|
58
|
+
oxford (optional): Whether to use an oxford comma. Default ``False``.
|
|
59
|
+
|
|
60
|
+
Returns:
|
|
61
|
+
Syntactically-correct list.
|
|
62
|
+
|
|
63
|
+
"""
|
|
64
|
+
if len(__l) < 2:
|
|
65
|
+
raise ValueError("list must contain at least two items")
|
|
66
|
+
|
|
67
|
+
separator = f"{',' if oxford else ''} {conjunction!s} "
|
|
68
|
+
result = separator.join([", ".join(__l[:-1]), __l[-1]])
|
|
69
|
+
return result
|
apytizer/utils/typing.py
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
|
|
3
|
+
# Standard Library Imports
|
|
4
|
+
from typing import Any
|
|
5
|
+
from typing import Iterable
|
|
6
|
+
from typing import Tuple
|
|
7
|
+
from typing import Type
|
|
8
|
+
from typing import Union
|
|
9
|
+
|
|
10
|
+
__all__ = ["allinstance"]
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def allinstance(
|
|
14
|
+
__objs: Iterable[Any],
|
|
15
|
+
__class_or_tuple: Union[Tuple[Type[Any], ...], type],
|
|
16
|
+
/,
|
|
17
|
+
) -> bool:
|
|
18
|
+
"""Whether all elements in an iterable object are instances of provided type(s).
|
|
19
|
+
|
|
20
|
+
Args:
|
|
21
|
+
__objs: Iterable object containing elements.
|
|
22
|
+
__class_or_tuple: Class or tuple of classes.
|
|
23
|
+
|
|
24
|
+
Returns:
|
|
25
|
+
Whether all elements are instances of the provided type(s).
|
|
26
|
+
|
|
27
|
+
"""
|
|
28
|
+
result = all(isinstance(elem, __class_or_tuple) for elem in __objs)
|
|
29
|
+
return result
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: apytizer
|
|
3
|
+
Version: 0.0.1b2
|
|
4
|
+
Summary: Implement wrappers quickly for REST APIs.
|
|
5
|
+
Project-URL: Homepage, https://github.com/seanssullivan/apytizer
|
|
6
|
+
Project-URL: Repository, https://github.com/seanssullivan/apytizer.git
|
|
7
|
+
Project-URL: Issues, https://github.com/seanssullivan/apytizer/issues
|
|
8
|
+
Author-email: Sean Sullivan <seansullivan@seanmedia.ca>
|
|
9
|
+
License-Expression: Apache-2.0
|
|
10
|
+
License-File: LICENSE
|
|
11
|
+
Classifier: Development Status :: 4 - Beta
|
|
12
|
+
Classifier: Intended Audience :: Developers
|
|
13
|
+
Classifier: License :: OSI Approved :: Apache Software License
|
|
14
|
+
Classifier: Natural Language :: English
|
|
15
|
+
Classifier: Operating System :: OS Independent
|
|
16
|
+
Classifier: Programming Language :: Python :: 3
|
|
17
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.8
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
22
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
23
|
+
Requires-Python: >=3.9
|
|
24
|
+
Requires-Dist: cachetools
|
|
25
|
+
Requires-Dist: requests
|
|
26
|
+
Provides-Extra: docs
|
|
27
|
+
Requires-Dist: sphinx>=2.0.0; extra == 'docs'
|
|
28
|
+
Provides-Extra: testing
|
|
29
|
+
Requires-Dist: cachetools; extra == 'testing'
|
|
30
|
+
Requires-Dist: coverage; extra == 'testing'
|
|
31
|
+
Requires-Dist: flask; extra == 'testing'
|
|
32
|
+
Requires-Dist: pytest; extra == 'testing'
|
|
33
|
+
Requires-Dist: pytest-cov; extra == 'testing'
|
|
34
|
+
Requires-Dist: pytest-env; extra == 'testing'
|
|
35
|
+
Requires-Dist: requests; extra == 'testing'
|
|
36
|
+
Requires-Dist: tox; extra == 'testing'
|
|
37
|
+
Description-Content-Type: text/markdown
|
|
38
|
+
|
|
39
|
+
# apytizer
|
|
40
|
+
|
|
41
|
+
Implement wrappers quickly for REST APIs.
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
apytizer/__init__.py,sha256=yzuWp_U0IBenCTMYUxVKBx_C8bsy6rUY15HGu0ylCsA,74
|
|
2
|
+
apytizer/errors.py,sha256=4GvnxBwo1hU98a8ZUBDfs3OYEeDN3kcZBlCTWjE1SSE,723
|
|
3
|
+
apytizer/http_methods.py,sha256=wMBhD20A8PDSXL2sxsS1oBMMCF0DthWVWkehAOOZ87A,744
|
|
4
|
+
apytizer/media_types.py,sha256=ptUcjYa1dLUGSHK__ETd55fi-kr9ZSglBtUAjlyJ8aw,3449
|
|
5
|
+
apytizer/protocols.py,sha256=NGhlpDC0BnCf58aydLjwWF4nUlYp_cRZaIAOcayS_ZQ,895
|
|
6
|
+
apytizer/adapters/__init__.py,sha256=G4T4wWieL9Wo4kgIvzroxFtnjYr14jxcWqFHrUNaTto,74
|
|
7
|
+
apytizer/adapters/transport_adapter.py,sha256=OH8DoE9h9PKn_yFOFjPZYGB5U_Pk1o1mFJGI7AnXpmk,2296
|
|
8
|
+
apytizer/apis/__init__.py,sha256=5t4pmOxHb6XmVvmo0ECyO84Ph7SR-uQyEImuzZgqNCs,124
|
|
9
|
+
apytizer/apis/abstract_api.py,sha256=lygtd3NgoLVYySCMlsvXSJiEErNe2eiV6HRyJ3FWRkY,826
|
|
10
|
+
apytizer/apis/web_api.py,sha256=PJSxHUz757BfJIWkMj3bITSVFI_0qTtVaUCKM7ACMVs,12906
|
|
11
|
+
apytizer/connections/__init__.py,sha256=wsaRficrSp-A8gCpL8CdLCf84TtNLSmKJnfo8AgYzkM,146
|
|
12
|
+
apytizer/connections/abstract_connection.py,sha256=3Q0PAhWF1Fr_GQm-yOu2m85AWb0lCWkuDfMd3snhcHg,646
|
|
13
|
+
apytizer/connections/http_connection.py,sha256=xXHTSIx5XbmVL0R2Y8MKPdjofhTlbd9_9v2WU8AFoNQ,12500
|
|
14
|
+
apytizer/decorators/__init__.py,sha256=wY-W8DuGwFFic78o02-wjJlIBAQ0Qc0G1syUZvSGj5s,158
|
|
15
|
+
apytizer/decorators/caching.py,sha256=mSTKorQfHzikIFm2KPvDr6l_tscAKVmC2K-Mpx-7aZI,2019
|
|
16
|
+
apytizer/decorators/chunking.py,sha256=yWtXcUV2396M9iuCeNxttT3w9IEfEL7KTOhgaG-j3uE,2690
|
|
17
|
+
apytizer/decorators/connection.py,sha256=iTclb0UuL-FeIXAZqVgCpop-XUDMwyCjzVFqWSVsLKk,1824
|
|
18
|
+
apytizer/decorators/json.py,sha256=06ofbA9vHZ54UlPABN6J4ZTH6zn_sdsmrlf8rfbtksY,1978
|
|
19
|
+
apytizer/decorators/pagination.py,sha256=wsaVf7h1NOTeEAeku6zD-hXxP2NJrHIEZNVrRmb1GBc,1936
|
|
20
|
+
apytizer/endpoints/__init__.py,sha256=HurARzunajUhxmyz1vxP-EJLybWLMJJDnjougREhZsA,139
|
|
21
|
+
apytizer/endpoints/abstract_endpoint.py,sha256=ASHZEDBTgx8fLntN7B72dyQrMTGkVQ9xZNodM9H9z58,919
|
|
22
|
+
apytizer/endpoints/web_endpoint.py,sha256=KNkTfvS9fOYSeSMQeywpMSuTNGkv2HurPaIUpppeiZM,15464
|
|
23
|
+
apytizer/engines/__init__.py,sha256=dkLBf3nNRJ0OcGXYeue_FE6E7Y4nGGJposbjtdy-mA4,134
|
|
24
|
+
apytizer/engines/abstract_engine.py,sha256=aljh99PCbD7giAkWgU8vk_ytJOnb3dk3UnlBZyagdDQ,959
|
|
25
|
+
apytizer/engines/http_engine.py,sha256=mvzjSEiDSa1yJ8-u5eYf2GWpt0SW8z-FvZuTVWhGJdw,4848
|
|
26
|
+
apytizer/factories/__init__.py,sha256=tV2VW2H4Fo8TrVNDsD9J-1Kl4IxuIy3fwoLtI9AlfFY,110
|
|
27
|
+
apytizer/factories/abstract_factory.py,sha256=XtvofT5-v824RCnBvD1Rqy_-ylXTw3XXXf6l4yteW50,361
|
|
28
|
+
apytizer/managers/__init__.py,sha256=wNg4SB_it89QYXLBv7dTNVP1DjmNwWW4F1F6Redkwno,311
|
|
29
|
+
apytizer/managers/abstract_manager.py,sha256=AlQdaGj4SGxMZ46BZA5m8pYXA9zJI9EgvJAHeGYLBa0,2145
|
|
30
|
+
apytizer/managers/base_manager.py,sha256=UeZS739UK8C7-IDB_t4CYPbEpOSkGSGE_BygHcEDv1I,2786
|
|
31
|
+
apytizer/mappers/__init__.py,sha256=OGhBhWu34G8UZnmwCIxcRAkXnJKDbyxnTCgJvhKr8JM,122
|
|
32
|
+
apytizer/mappers/abstract_mapper.py,sha256=rqKzr4QcyFFrebPktvwuIGGI1RWq6ELoL344DgiOQyI,1113
|
|
33
|
+
apytizer/mappers/base_mapper.py,sha256=SOx1RuZufytD8y-NSuErp22sgDqBFVZXiyo2JAMGGL0,2154
|
|
34
|
+
apytizer/models/__init__.py,sha256=73LwJufUqhc_vwajlWIqSPxmOam9qj6hY-DdpaU93kg,131
|
|
35
|
+
apytizer/models/abstract_model.py,sha256=_utDDwRTDnhepEfwapF9HGH3Zy2ZLKMwNMS5BjmWxuo,3000
|
|
36
|
+
apytizer/models/base_model.py,sha256=lXfTxws7q1PoG3jSPbuSS0FJ9BQz4xqbbiz5qSduf9g,2126
|
|
37
|
+
apytizer/repositories/__init__.py,sha256=JlJyfHxZ5K5N7vWe-CJWvK2NHsxuldaRmKn6dfrpcUs,150
|
|
38
|
+
apytizer/repositories/abstract_repository.py,sha256=P0q8olfi-Za_YQCCnmIxdFN-PFjvZtY-mzaAN9AUBnQ,2214
|
|
39
|
+
apytizer/repositories/managed_repository.py,sha256=wpKWt1tO02SIF0_TG-QBBQ56Lk0n3LFKTWrZXnOSU2A,2195
|
|
40
|
+
apytizer/routes/__init__.py,sha256=nR2RRWJRPAXN6ph1mOkq7El5phFj1xzHa3HDZyLqbEM,131
|
|
41
|
+
apytizer/routes/abstract_route.py,sha256=DD2rg-AvUUy90cjyc35QiqE3t6APRN_g8EvNk0-YZUg,754
|
|
42
|
+
apytizer/routes/base_route.py,sha256=lRbF6TIgzPu2DPa8u6NiClCLiNFjapckG7bPvxIsIwM,3709
|
|
43
|
+
apytizer/sessions/__init__.py,sha256=1rwoAfpR5LF3LPJXbXjk6-jlBjESGsChRDSkWSt4FQM,944
|
|
44
|
+
apytizer/sessions/abstract_session.py,sha256=YS6KVGBFC7zWYir3Zvefy-crhsfojfFYpSCPZmdYYpI,1471
|
|
45
|
+
apytizer/sessions/requests_session.py,sha256=ZMTcK6meDHnzdtlYwN3hdnu3lQJ_L8FkdzkJ_xgb64k,3730
|
|
46
|
+
apytizer/states/__init__.py,sha256=-Q6fJtW3HKXbjfrRnuN8cF-Txs1grWVTXWZq7yVbCRs,132
|
|
47
|
+
apytizer/states/abstract_state.py,sha256=7wGAl0NWkUxjKsDKm6o_6nAIptiO1T2zl_qS3pFOx7U,1861
|
|
48
|
+
apytizer/states/local_state.py,sha256=thLaTmCOAPAUwnPZ24bCKWfSDM8VxFwkSlNoJWwvvHk,2490
|
|
49
|
+
apytizer/utils/__init__.py,sha256=qTVMHm1Ub01zfxsbQLmaPwxiWPbEBdOPy_h158SI2f4,240
|
|
50
|
+
apytizer/utils/caching.py,sha256=bhAgZBDdhyPuUATkbYpYgVhwcuoPiu7zso4TaS9vIjg,837
|
|
51
|
+
apytizer/utils/dictionaries.py,sha256=ZdkGac9AWvvKACLRH4Vua-Tf_dkcYeJaXXc_8-7vCTo,9561
|
|
52
|
+
apytizer/utils/errors.py,sha256=yGYgPB-IDvJ-zSpVNq6LVL-ppVDJTC33vSKo-QNJBzY,2803
|
|
53
|
+
apytizer/utils/iterables.py,sha256=aCxh_rfauIRUH_vvPfDLfBL7zgfIMtdC33ZHPi0yTO8,2314
|
|
54
|
+
apytizer/utils/objects.py,sha256=ev53gZuATc2GwLjR0zH0e7zqkL7mEpFeg6waxI8h-FI,3889
|
|
55
|
+
apytizer/utils/strings.py,sha256=Qu2wkjduMybibclhldJgHWVY5GMvsSZ3fUDtPXyzx5w,1588
|
|
56
|
+
apytizer/utils/typing.py,sha256=H2nVGreAEMdW1VzAbdaGVLOHVn2HUXXRhw4M47b47rI,709
|
|
57
|
+
apytizer-0.0.1b2.dist-info/METADATA,sha256=4NKAX4iGRjb9wclOLI0I0Vd2zfmup6rCOmsLp3-68dQ,1621
|
|
58
|
+
apytizer-0.0.1b2.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
59
|
+
apytizer-0.0.1b2.dist-info/licenses/LICENSE,sha256=rwTrW8f9E015utDMKkNmSWxjW22qM-BDH6xSiLw0lGQ,10351
|
|
60
|
+
apytizer-0.0.1b2.dist-info/RECORD,,
|
apytizer/abstracts/__init__.py
DELETED
apytizer/abstracts/api.py
DELETED
|
@@ -1,147 +0,0 @@
|
|
|
1
|
-
# -*- coding: utf-8 -*-
|
|
2
|
-
"""Abstract API class interface.
|
|
3
|
-
|
|
4
|
-
This module defines an abstract API class which provides an interface
|
|
5
|
-
for subclasses to implement. Each of the abstract methods represents
|
|
6
|
-
a standard HTTP request method.
|
|
7
|
-
|
|
8
|
-
"""
|
|
9
|
-
|
|
10
|
-
# Third-Party Imports
|
|
11
|
-
from __future__ import annotations
|
|
12
|
-
import abc
|
|
13
|
-
from typing import Dict, Tuple, Union
|
|
14
|
-
|
|
15
|
-
# Third-Party Imports
|
|
16
|
-
from requests import Response
|
|
17
|
-
from requests.auth import AuthBase
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
class AbstractAPI(abc.ABC):
|
|
21
|
-
"""
|
|
22
|
-
Represents an abstract API.
|
|
23
|
-
"""
|
|
24
|
-
url: str
|
|
25
|
-
auth: Union[AuthBase, Tuple]
|
|
26
|
-
|
|
27
|
-
def __eq__(self, other: AbstractAPI) -> bool:
|
|
28
|
-
return other.url == self.url \
|
|
29
|
-
and other.auth == self.auth
|
|
30
|
-
|
|
31
|
-
def __hash__(self) -> int:
|
|
32
|
-
return hash(self.url)
|
|
33
|
-
|
|
34
|
-
def __repr__(self) -> str:
|
|
35
|
-
return f'<{self.__class__.__name__!s} url={self.url!s}>'
|
|
36
|
-
|
|
37
|
-
@abc.abstractmethod
|
|
38
|
-
def head(self, route: str, *args, headers: Dict = None, **kwargs) -> Response:
|
|
39
|
-
"""
|
|
40
|
-
Abstract method for sending an HTTP HEAD request.
|
|
41
|
-
|
|
42
|
-
Returns:
|
|
43
|
-
Response object.
|
|
44
|
-
|
|
45
|
-
.. _MDN Web Docs:
|
|
46
|
-
https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/HEAD
|
|
47
|
-
|
|
48
|
-
"""
|
|
49
|
-
raise NotImplementedError
|
|
50
|
-
|
|
51
|
-
@abc.abstractmethod
|
|
52
|
-
def get(self, route: str, *args, headers: Dict = None, **kwargs) -> Response:
|
|
53
|
-
"""
|
|
54
|
-
Abstract method for sending an HTTP GET request.
|
|
55
|
-
|
|
56
|
-
Returns:
|
|
57
|
-
Response object.
|
|
58
|
-
|
|
59
|
-
.. _MDN Web Docs:
|
|
60
|
-
https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/GET
|
|
61
|
-
|
|
62
|
-
"""
|
|
63
|
-
raise NotImplementedError
|
|
64
|
-
|
|
65
|
-
@abc.abstractmethod
|
|
66
|
-
def post(self, route: str, *args, headers: Dict = None, **kwargs) -> Response:
|
|
67
|
-
"""
|
|
68
|
-
Abstract method for sending an HTTP POST request.
|
|
69
|
-
|
|
70
|
-
Returns:
|
|
71
|
-
Response object.
|
|
72
|
-
|
|
73
|
-
.. _MDN Web Docs:
|
|
74
|
-
https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/POST
|
|
75
|
-
|
|
76
|
-
"""
|
|
77
|
-
raise NotImplementedError
|
|
78
|
-
|
|
79
|
-
@abc.abstractmethod
|
|
80
|
-
def put(self, route: str, *args, headers: Dict = None, **kwargs) -> Response:
|
|
81
|
-
"""
|
|
82
|
-
Abstract method for sending an HTTP PUT request.
|
|
83
|
-
|
|
84
|
-
Returns:
|
|
85
|
-
Response object.
|
|
86
|
-
|
|
87
|
-
.. _MDN Web Docs:
|
|
88
|
-
https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/PUT
|
|
89
|
-
|
|
90
|
-
"""
|
|
91
|
-
raise NotImplementedError
|
|
92
|
-
|
|
93
|
-
@abc.abstractmethod
|
|
94
|
-
def patch(self, route: str, *args, headers: Dict = None, **kwargs) -> Response:
|
|
95
|
-
"""
|
|
96
|
-
Abstract method for sending an HTTP PATCH request.
|
|
97
|
-
|
|
98
|
-
Returns:
|
|
99
|
-
Response object.
|
|
100
|
-
|
|
101
|
-
.. _MDN Web Docs:
|
|
102
|
-
https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/PATCH
|
|
103
|
-
|
|
104
|
-
"""
|
|
105
|
-
raise NotImplementedError
|
|
106
|
-
|
|
107
|
-
@abc.abstractmethod
|
|
108
|
-
def delete(self, route: str, *args, headers: Dict = None, **kwargs) -> Response:
|
|
109
|
-
"""
|
|
110
|
-
Abstract method for sending an HTTP DELETE request.
|
|
111
|
-
|
|
112
|
-
Returns:
|
|
113
|
-
Response object.
|
|
114
|
-
|
|
115
|
-
.. _MDN Web Docs:
|
|
116
|
-
https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/DELETE
|
|
117
|
-
|
|
118
|
-
"""
|
|
119
|
-
raise NotImplementedError
|
|
120
|
-
|
|
121
|
-
@abc.abstractmethod
|
|
122
|
-
def options(self, route: str, *args, headers: Dict = None, **kwargs) -> Response:
|
|
123
|
-
"""
|
|
124
|
-
Abstract method for sending an HTTP OPTIONS request.
|
|
125
|
-
|
|
126
|
-
Returns:
|
|
127
|
-
Response object.
|
|
128
|
-
|
|
129
|
-
.. _MDN Web Docs:
|
|
130
|
-
https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/OPTIONS
|
|
131
|
-
|
|
132
|
-
"""
|
|
133
|
-
raise NotImplementedError
|
|
134
|
-
|
|
135
|
-
@abc.abstractmethod
|
|
136
|
-
def trace(self, route: str, *args, headers: Dict = None, **kwargs) -> Response:
|
|
137
|
-
"""
|
|
138
|
-
Abstract method for sending an HTTP TRACE request.
|
|
139
|
-
|
|
140
|
-
Returns:
|
|
141
|
-
Response object.
|
|
142
|
-
|
|
143
|
-
.. _MDN Web Docs:
|
|
144
|
-
https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/TRACE
|
|
145
|
-
|
|
146
|
-
"""
|
|
147
|
-
raise NotImplementedError
|
apytizer/abstracts/endpoint.py
DELETED
|
@@ -1,177 +0,0 @@
|
|
|
1
|
-
# -*- coding: utf-8 -*-
|
|
2
|
-
"""Abstract endpoint class interface.
|
|
3
|
-
|
|
4
|
-
This module defines an abstract endpoint class which provides an interface
|
|
5
|
-
for subclasses to implement. Each of the abstract methods represents
|
|
6
|
-
a standard HTTP request method.
|
|
7
|
-
|
|
8
|
-
"""
|
|
9
|
-
|
|
10
|
-
# Third-Party Imports
|
|
11
|
-
import abc
|
|
12
|
-
from urllib.parse import urljoin
|
|
13
|
-
|
|
14
|
-
# Third-Party Imports
|
|
15
|
-
from requests import Response
|
|
16
|
-
|
|
17
|
-
# Local Imports
|
|
18
|
-
from .api import AbstractAPI
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
class AbstractEndpoint(abc.ABC):
|
|
22
|
-
"""
|
|
23
|
-
Represents an abstract endpoint.
|
|
24
|
-
|
|
25
|
-
Attributes:
|
|
26
|
-
api: Instance of an API subclass.
|
|
27
|
-
path: Relative path to API endpoint.
|
|
28
|
-
|
|
29
|
-
"""
|
|
30
|
-
api: AbstractAPI
|
|
31
|
-
path: str
|
|
32
|
-
|
|
33
|
-
@property
|
|
34
|
-
def uri(self) -> str:
|
|
35
|
-
"""Retrieve the endpoint URI."""
|
|
36
|
-
return urljoin(self.api.url, self.path)
|
|
37
|
-
|
|
38
|
-
@property
|
|
39
|
-
def url(self) -> str:
|
|
40
|
-
return self.uri
|
|
41
|
-
|
|
42
|
-
def __hash__(self) -> int:
|
|
43
|
-
return hash(self.uri)
|
|
44
|
-
|
|
45
|
-
def __repr__(self) -> str:
|
|
46
|
-
return f'<{self.__class__.__name__!s} uri={self.uri!s}>'
|
|
47
|
-
|
|
48
|
-
def __str__(self) -> str:
|
|
49
|
-
return f'{self.uri!s}'
|
|
50
|
-
|
|
51
|
-
@abc.abstractmethod
|
|
52
|
-
def head(self, *args, **kwargs) -> Response:
|
|
53
|
-
"""
|
|
54
|
-
Abstract method for sending an HTTP HEAD request.
|
|
55
|
-
|
|
56
|
-
This method must call the `head` method on the component API instance.
|
|
57
|
-
|
|
58
|
-
Returns:
|
|
59
|
-
Response object.
|
|
60
|
-
|
|
61
|
-
.. _MDN Web Docs:
|
|
62
|
-
https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/HEAD
|
|
63
|
-
|
|
64
|
-
"""
|
|
65
|
-
raise NotImplementedError
|
|
66
|
-
|
|
67
|
-
@abc.abstractmethod
|
|
68
|
-
def get(self, *args, **kwargs) -> Response:
|
|
69
|
-
"""
|
|
70
|
-
Abstract method for sending an HTTP GET request.
|
|
71
|
-
|
|
72
|
-
This method must call the `get` method on the component API instance.
|
|
73
|
-
|
|
74
|
-
Returns:
|
|
75
|
-
Response object.
|
|
76
|
-
|
|
77
|
-
.. _MDN Web Docs:
|
|
78
|
-
https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/GET
|
|
79
|
-
|
|
80
|
-
"""
|
|
81
|
-
raise NotImplementedError
|
|
82
|
-
|
|
83
|
-
@abc.abstractmethod
|
|
84
|
-
def post(self, *args, **kwargs) -> Response:
|
|
85
|
-
"""
|
|
86
|
-
Abstract method for sending an HTTP POST request.
|
|
87
|
-
|
|
88
|
-
This method must call the `post` method on the component API instance.
|
|
89
|
-
|
|
90
|
-
Returns:
|
|
91
|
-
Response object.
|
|
92
|
-
|
|
93
|
-
.. _MDN Web Docs:
|
|
94
|
-
https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/POST
|
|
95
|
-
|
|
96
|
-
"""
|
|
97
|
-
raise NotImplementedError
|
|
98
|
-
|
|
99
|
-
@abc.abstractmethod
|
|
100
|
-
def put(self, *args, **kwargs) -> Response:
|
|
101
|
-
"""
|
|
102
|
-
Abstract method for sending an HTTP PUT request.
|
|
103
|
-
|
|
104
|
-
This method must call the `put` method on the component API instance.
|
|
105
|
-
|
|
106
|
-
Returns:
|
|
107
|
-
Response object.
|
|
108
|
-
|
|
109
|
-
.. _MDN Web Docs:
|
|
110
|
-
https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/PUT
|
|
111
|
-
|
|
112
|
-
"""
|
|
113
|
-
raise NotImplementedError
|
|
114
|
-
|
|
115
|
-
@abc.abstractmethod
|
|
116
|
-
def patch(self, *args, **kwargs) -> Response:
|
|
117
|
-
"""
|
|
118
|
-
Abstract method for sending an HTTP PATCH request.
|
|
119
|
-
|
|
120
|
-
This method must call the `patch` method on the component API instance.
|
|
121
|
-
|
|
122
|
-
Returns:
|
|
123
|
-
Response object.
|
|
124
|
-
|
|
125
|
-
.. _MDN Web Docs:
|
|
126
|
-
https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/PATCH
|
|
127
|
-
|
|
128
|
-
"""
|
|
129
|
-
raise NotImplementedError
|
|
130
|
-
|
|
131
|
-
@abc.abstractmethod
|
|
132
|
-
def delete(self, *args, **kwargs) -> Response:
|
|
133
|
-
"""
|
|
134
|
-
Abstract method for sending an HTTP DELETE request.
|
|
135
|
-
|
|
136
|
-
This method must call the `delete` method on the component API instance.
|
|
137
|
-
|
|
138
|
-
Returns:
|
|
139
|
-
Response object.
|
|
140
|
-
|
|
141
|
-
.. _MDN Web Docs:
|
|
142
|
-
https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/DELETE
|
|
143
|
-
|
|
144
|
-
"""
|
|
145
|
-
raise NotImplementedError
|
|
146
|
-
|
|
147
|
-
@abc.abstractmethod
|
|
148
|
-
def options(self, *args, **kwargs) -> Response:
|
|
149
|
-
"""
|
|
150
|
-
Abstract method for sending an HTTP OPTIONS request.
|
|
151
|
-
|
|
152
|
-
This method must call the `options` method on the component API instance.
|
|
153
|
-
|
|
154
|
-
Returns:
|
|
155
|
-
Response object.
|
|
156
|
-
|
|
157
|
-
.. _MDN Web Docs:
|
|
158
|
-
https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/OPTIONS
|
|
159
|
-
|
|
160
|
-
"""
|
|
161
|
-
raise NotImplementedError
|
|
162
|
-
|
|
163
|
-
@abc.abstractmethod
|
|
164
|
-
def trace(self, *args, **kwargs) -> Response:
|
|
165
|
-
"""
|
|
166
|
-
Abstract method for sending an HTTP TRACE request.
|
|
167
|
-
|
|
168
|
-
This method must call the `trace` method on the component API instance.
|
|
169
|
-
|
|
170
|
-
Returns:
|
|
171
|
-
Response object.
|
|
172
|
-
|
|
173
|
-
.. _MDN Web Docs:
|
|
174
|
-
https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/TRACE
|
|
175
|
-
|
|
176
|
-
"""
|
|
177
|
-
raise NotImplementedError
|
apytizer/abstracts/model.py
DELETED
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
# -*- coding: utf-8 -*-
|
|
2
|
-
"""Abstract model class interface.
|
|
3
|
-
|
|
4
|
-
This module defines an abstract model class which provides an interface
|
|
5
|
-
for subclasses to implement.
|
|
6
|
-
|
|
7
|
-
"""
|
|
8
|
-
|
|
9
|
-
# Standard Library Imports
|
|
10
|
-
from __future__ import annotations
|
|
11
|
-
import abc
|
|
12
|
-
from typing import Mapping
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
class AbstractModel(abc.ABC):
|
|
16
|
-
"""
|
|
17
|
-
Represents an abstract model.
|
|
18
|
-
|
|
19
|
-
"""
|
|
20
|
-
state: Mapping
|
|
21
|
-
|
|
22
|
-
@abc.abstractmethod
|
|
23
|
-
def __eq__(self, other: AbstractModel) -> bool:
|
|
24
|
-
"""
|
|
25
|
-
Abstract method for determining whether model is equal to another.
|
|
26
|
-
|
|
27
|
-
Returns:
|
|
28
|
-
Whether models are equal.
|
|
29
|
-
|
|
30
|
-
"""
|
|
31
|
-
raise NotImplementedError
|
|
32
|
-
|
|
33
|
-
@abc.abstractmethod
|
|
34
|
-
def get(self, keys: str, default = None):
|
|
35
|
-
"""
|
|
36
|
-
Abstract method for getting model property from state.
|
|
37
|
-
|
|
38
|
-
Returns:
|
|
39
|
-
Value of property in model state.
|
|
40
|
-
|
|
41
|
-
"""
|
|
42
|
-
raise NotImplementedError
|
|
43
|
-
|
|
44
|
-
@abc.abstractmethod
|
|
45
|
-
def update(self, __m: Mapping = None, **kwargs) -> None:
|
|
46
|
-
"""
|
|
47
|
-
Abstract method for updating model state.
|
|
48
|
-
|
|
49
|
-
"""
|
|
50
|
-
raise NotImplementedError
|
apytizer/abstracts/session.py
DELETED
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
# -*- coding: utf-8 -*-
|
|
2
|
-
"""Abstract session class interface.
|
|
3
|
-
|
|
4
|
-
This module defines an abstract session class which provides an interface
|
|
5
|
-
for subclasses to implement.
|
|
6
|
-
|
|
7
|
-
"""
|
|
8
|
-
|
|
9
|
-
# Third-Party Imports
|
|
10
|
-
from __future__ import annotations
|
|
11
|
-
import abc
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
class AbstractSession(abc.ABC):
|
|
15
|
-
"""
|
|
16
|
-
Represents an abstract session.
|
|
17
|
-
"""
|
|
18
|
-
|
|
19
|
-
def __enter__(self):
|
|
20
|
-
"""
|
|
21
|
-
Starts the session as a context manager.
|
|
22
|
-
"""
|
|
23
|
-
self.start()
|
|
24
|
-
|
|
25
|
-
def __exit__(self, *args):
|
|
26
|
-
"""
|
|
27
|
-
Closes the session as context manager.
|
|
28
|
-
"""
|
|
29
|
-
self.close(*args)
|
|
30
|
-
|
|
31
|
-
@abc.abstractmethod
|
|
32
|
-
def start(self):
|
|
33
|
-
"""Starts the session."""
|
|
34
|
-
raise NotImplementedError
|
|
35
|
-
|
|
36
|
-
@abc.abstractmethod
|
|
37
|
-
def close(self):
|
|
38
|
-
"""Closes the session."""
|
|
39
|
-
raise NotImplementedError
|
apytizer/adapters/transport.py
DELETED
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
# -*- coding: utf-8 -*-
|
|
2
|
-
"""Transport Adapter.
|
|
3
|
-
|
|
4
|
-
This module defines a transport adapter class: an implementation of an
|
|
5
|
-
HTTPAdapter which handles exponential backoff for retrying requests and
|
|
6
|
-
provides default values for rate limiting and request timeout.
|
|
7
|
-
|
|
8
|
-
"""
|
|
9
|
-
|
|
10
|
-
# Standard Library Imports
|
|
11
|
-
from urllib3.util import Retry
|
|
12
|
-
|
|
13
|
-
# Third-Party Imports
|
|
14
|
-
from requests import PreparedRequest
|
|
15
|
-
from requests import Response
|
|
16
|
-
from requests.adapters import HTTPAdapter
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
class TransportAdapter(HTTPAdapter):
|
|
20
|
-
"""
|
|
21
|
-
Implementation of a transport adaptor.
|
|
22
|
-
|
|
23
|
-
Transport adapters define methods for interacting with HTTP services,
|
|
24
|
-
enabling the use of per-service configurations.
|
|
25
|
-
|
|
26
|
-
"""
|
|
27
|
-
|
|
28
|
-
def __init__(self, *args, **kwargs):
|
|
29
|
-
kwargs.setdefault('max_retries', Retry(
|
|
30
|
-
total=10,
|
|
31
|
-
status_forcelist=[413, 429, 500, 502, 503, 504],
|
|
32
|
-
allowed_methods=["HEAD", "GET", "POST", "PUT", "PATCH", "DELETE", "OPTIONS", "TRACE"],
|
|
33
|
-
backoff_factor=kwargs.pop('rate_limit', 1)
|
|
34
|
-
))
|
|
35
|
-
self.timeout = kwargs.pop('timeout', 5)
|
|
36
|
-
super().__init__(*args, **kwargs)
|
|
37
|
-
|
|
38
|
-
def send(self, request: PreparedRequest, **kwargs) -> Response:
|
|
39
|
-
kwargs.setdefault('timeout', self.timeout)
|
|
40
|
-
return super().send(request, **kwargs)
|