Switches python-experimental in as the primary python client (#13501)

* Changes python to python-prior

* python -> python-prior, python-experimental->python

* Renames sample spec directories

* Samples regnerated

* Regenerates docs

* Fixes test

* Samples regenerated

* Updates renerators list

* Fixes made to python paths in pom.xml

* Fixes node4 sh file paths
This commit is contained in:
Justin Black
2022-09-24 01:19:38 -07:00
committed by GitHub
parent 9d621342e0
commit 7e73645303
3628 changed files with 49326 additions and 45313 deletions

View File

@@ -33,6 +33,7 @@ var/
# Installer logs
pip-log.txt
pip-delete-this-directory.txt
dev-requirements.txt.log
# Unit test / coverage reports
htmlcov/

View File

@@ -10,6 +10,9 @@ stages:
- pip install -r test-requirements.txt
- pytest --cov=dynamic_servers
test-3.5:
extends: .tests
image: python:3.5-alpine
test-3.6:
extends: .tests
image: python:3.6-alpine
@@ -19,6 +22,3 @@ test-3.7:
test-3.8:
extends: .tests
image: python:3.8-alpine
test-3.9:
extends: .tests
image: python:3.9-alpine

View File

@@ -2,22 +2,22 @@
.gitlab-ci.yml
.travis.yml
README.md
docs/UsageApi.md
docs/apis/tags/UsageApi.md
dynamic_servers/__init__.py
dynamic_servers/api/__init__.py
dynamic_servers/api/usage_api.py
dynamic_servers/api_client.py
dynamic_servers/apis/__init__.py
dynamic_servers/apis/tags/usage_api.py
dynamic_servers/configuration.py
dynamic_servers/exceptions.py
dynamic_servers/model/__init__.py
dynamic_servers/model_utils.py
dynamic_servers/models/__init__.py
dynamic_servers/rest.py
dynamic_servers/schemas.py
git_push.sh
requirements.txt
setup.cfg
setup.py
test-requirements.txt
test/__init__.py
test/test_models/__init__.py
tox.ini

View File

@@ -1,10 +1,10 @@
# ref: https://docs.travis-ci.com/user/languages/python
language: python
python:
- "3.5"
- "3.6"
- "3.7"
- "3.8"
- "3.9"
# command to install dependencies
install:
- "pip install -r requirements.txt"

View File

@@ -9,7 +9,98 @@ This Python package is automatically generated by the [OpenAPI Generator](https:
## Requirements.
Python >=3.6
Python >=3.7
## Migration from other generators like python and python-legacy
### Changes
1. This generator uses spec case for all (object) property names and parameter names.
- So if the spec has a property name like camelCase, it will use camelCase rather than camel_case
- So you will need to update how you input and read properties to use spec case
2. Endpoint parameters are stored in dictionaries to prevent collisions (explanation below)
- So you will need to update how you pass data in to endpoints
3. Endpoint responses now include the original response, the deserialized response body, and (todo)the deserialized headers
- So you will need to update your code to use response.body to access deserialized data
4. All validated data is instantiated in an instance that subclasses all validated Schema classes and Decimal/str/list/tuple/frozendict/NoneClass/BoolClass/bytes/io.FileIO
- This means that you can use isinstance to check if a payload validated against a schema class
- This means that no data will be of type None/True/False
- ingested None will subclass NoneClass
- ingested True will subclass BoolClass
- ingested False will subclass BoolClass
- So if you need to check is True/False/None, instead use instance.is_true_oapg()/.is_false_oapg()/.is_none_oapg()
5. All validated class instances are immutable except for ones based on io.File
- This is because if properties were changed after validation, that validation would no longer apply
- So no changing values or property values after a class has been instantiated
6. String + Number types with formats
- String type data is stored as a string and if you need to access types based on its format like date,
date-time, uuid, number etc then you will need to use accessor functions on the instance
- type string + format: See .as_date_oapg, .as_datetime_oapg, .as_decimal_oapg, .as_uuid_oapg
- type number + format: See .as_float_oapg, .as_int_oapg
- this was done because openapi/json-schema defines constraints. string data may be type string with no format
keyword in one schema, and include a format constraint in another schema
- So if you need to access a string format based type, use as_date_oapg/as_datetime_oapg/as_decimal_oapg/as_uuid_oapg
- So if you need to access a number format based type, use as_int_oapg/as_float_oapg
7. Property access on AnyType(type unset) or object(dict) schemas
- Only required keys with valid python names are properties like .someProp and have type hints
- All optional keys may not exist, so properties are not defined for them
- One can access optional values with dict_instance['optionalProp'] and KeyError will be raised if it does not exist
- Use get_item_oapg if you need a way to always get a value whether or not the key exists
- If the key does not exist, schemas.unset is returned from calling dict_instance.get_item_oapg('optionalProp')
- All required and optional keys have type hints for this method, and @typing.overload is used
- A type hint is also generated for additionalProperties accessed using this method
- So you will need to update you code to use some_instance['optionalProp'] to access optional property
and additionalProperty values
8. The location of the api classes has changed
- Api classes are located in your_package.apis.tags.some_api
- This change was made to eliminate redundant code generation
- Legacy generators generated the same endpoint twice if it had > 1 tag on it
- This generator defines an endpoint in one class, then inherits that class to generate
apis by tags and by paths
- This change reduces code and allows quicker run time if you use the path apis
- path apis are at your_package.apis.paths.some_path
- Those apis will only load their needed models, which is less to load than all of the resources needed in a tag api
- So you will need to update your import paths to the api classes
### Why are Oapg and _oapg used in class and method names?
Classes can have arbitrarily named properties set on them
Endpoints can have arbitrary operationId method names set
For those reasons, I use the prefix Oapg and _oapg to greatly reduce the likelihood of collisions
on protected + public classes/methods.
oapg stands for OpenApi Python Generator.
### Object property spec case
This was done because when payloads are ingested, they can be validated against N number of schemas.
If the input signature used a different property name then that has mutated the payload.
So SchemaA and SchemaB must both see the camelCase spec named variable.
Also it is possible to send in two properties, named camelCase and camel_case in the same payload.
That use case should be support so spec case is used.
### Parameter spec case
Parameters can be included in different locations including:
- query
- path
- header
- cookie
Any of those parameters could use the same parameter names, so if every parameter
was included as an endpoint parameter in a function signature, they would collide.
For that reason, each of those inputs have been separated out into separate typed dictionaries:
- query_params
- path_params
- header_params
- cookie_params
So when updating your code, you will need to pass endpoint parameters in using those
dictionaries.
### Endpoint responses
Endpoint responses have been enriched to now include more information.
Any response reom an endpoint will now include the following properties:
response: urllib3.HTTPResponse
body: typing.Union[Unset, Schema]
headers: typing.Union[Unset, TODO]
Note: response header deserialization has not yet been added
## Installation & Usage
### pip install
@@ -49,7 +140,7 @@ Please follow the [installation procedure](#installation--usage) and then run th
import time
import dynamic_servers
from pprint import pprint
from dynamic_servers.api import usage_api
from dynamic_servers.apis import usage_api
# Defining the host is optional and defaults to http://petstore.swagger.io:80/v2
# See configuration.py for a list of all supported configuration parameters.
configuration = dynamic_servers.Configuration(
@@ -57,12 +148,11 @@ configuration = dynamic_servers.Configuration(
)
# Enter a context with an instance of the API client
with dynamic_servers.ApiClient(configuration) as api_client:
# Create an instance of the API class
api_instance = usage_api.UsageApi(api_client)
try:
# Use custom server
api_response = api_instance.custom_server()
@@ -77,14 +167,12 @@ All URIs are relative to *http://petstore.swagger.io:80/v2*
Class | Method | HTTP request | Description
------------ | ------------- | ------------- | -------------
*UsageApi* | [**custom_server**](docs/UsageApi.md#custom_server) | **GET** /custom | Use custom server
*UsageApi* | [**default_server**](docs/UsageApi.md#default_server) | **GET** /default | Use default server
*UsageApi* | [**custom_server**](docs/apis/tags/UsageApi.md#custom_server) | **get** /custom | Use custom server
*UsageApi* | [**default_server**](docs/apis/tags/UsageApi.md#default_server) | **get** /default | Use default server
## Documentation For Models
## Documentation For Authorization
All endpoints do not require authorization.
@@ -93,17 +181,16 @@ Class | Method | HTTP request | Description
## Notes for Large OpenAPI documents
If the OpenAPI document is large, imports in dynamic_servers.apis and dynamic_servers.models may fail with a
RecursionError indicating the maximum recursion limit has been exceeded. In that case, there are a couple of solutions:
Solution 1:
Use specific imports for apis and models like:
- `from dynamic_servers.api.default_api import DefaultApi`
- `from dynamic_servers.apis.default_api import DefaultApi`
- `from dynamic_servers.model.pet import Pet`
Solution 2:
Solution 1:
Before importing the package, adjust the maximum recursion limit as shown below:
```
import sys
@@ -112,4 +199,3 @@ import dynamic_servers
from dynamic_servers.apis import *
from dynamic_servers.models import *
```

View File

@@ -0,0 +1,136 @@
<a name="__pageTop"></a>
# dynamic_servers.apis.tags.usage_api.UsageApi
All URIs are relative to *http://petstore.swagger.io:80/v2*
Method | HTTP request | Description
------------- | ------------- | -------------
[**custom_server**](#custom_server) | **get** /custom | Use custom server
[**default_server**](#default_server) | **get** /default | Use default server
# **custom_server**
<a name="custom_server"></a>
> {str: (bool, date, datetime, dict, float, int, list, str, none_type)} custom_server()
Use custom server
Use custom server
### Example
```python
import dynamic_servers
from dynamic_servers.apis.tags import usage_api
from pprint import pprint
# Defining the host is optional and defaults to http://petstore.swagger.io:80/v2
# See configuration.py for a list of all supported configuration parameters.
configuration = dynamic_servers.Configuration(
host = "http://petstore.swagger.io:80/v2"
)
# Enter a context with an instance of the API client
with dynamic_servers.ApiClient(configuration) as api_client:
# Create an instance of the API class
api_instance = usage_api.UsageApi(api_client)
# example, this endpoint has no required or optional parameters
try:
# Use custom server
api_response = api_instance.custom_server()
pprint(api_response)
except dynamic_servers.ApiException as e:
print("Exception when calling UsageApi->custom_server: %s\n" % e)
```
### Parameters
This endpoint does not need any parameter.
### Return Types, Responses
Code | Class | Description
------------- | ------------- | -------------
n/a | api_client.ApiResponseWithoutDeserialization | When skip_deserialization is True this response is returned
200 | [ApiResponseFor200](#custom_server.ApiResponseFor200) | successful operation
#### custom_server.ApiResponseFor200
Name | Type | Description | Notes
------------- | ------------- | ------------- | -------------
response | urllib3.HTTPResponse | Raw response |
body | typing.Union[SchemaFor200ResponseBodyApplicationJson, ] | |
headers | Unset | headers were not defined |
# SchemaFor200ResponseBodyApplicationJson
## Model Type Info
Input Type | Accessed Type | Description | Notes
------------ | ------------- | ------------- | -------------
dict, frozendict.frozendict, | frozendict.frozendict, | |
### Authorization
No authorization required
[[Back to top]](#__pageTop) [[Back to API list]](../../../README.md#documentation-for-api-endpoints) [[Back to Model list]](../../../README.md#documentation-for-models) [[Back to README]](../../../README.md)
# **default_server**
<a name="default_server"></a>
> {str: (bool, date, datetime, dict, float, int, list, str, none_type)} default_server()
Use default server
Use default server
### Example
```python
import dynamic_servers
from dynamic_servers.apis.tags import usage_api
from pprint import pprint
# Defining the host is optional and defaults to http://petstore.swagger.io:80/v2
# See configuration.py for a list of all supported configuration parameters.
configuration = dynamic_servers.Configuration(
host = "http://petstore.swagger.io:80/v2"
)
# Enter a context with an instance of the API client
with dynamic_servers.ApiClient(configuration) as api_client:
# Create an instance of the API class
api_instance = usage_api.UsageApi(api_client)
# example, this endpoint has no required or optional parameters
try:
# Use default server
api_response = api_instance.default_server()
pprint(api_response)
except dynamic_servers.ApiException as e:
print("Exception when calling UsageApi->default_server: %s\n" % e)
```
### Parameters
This endpoint does not need any parameter.
### Return Types, Responses
Code | Class | Description
------------- | ------------- | -------------
n/a | api_client.ApiResponseWithoutDeserialization | When skip_deserialization is True this response is returned
200 | [ApiResponseFor200](#default_server.ApiResponseFor200) | successful operation
#### default_server.ApiResponseFor200
Name | Type | Description | Notes
------------- | ------------- | ------------- | -------------
response | urllib3.HTTPResponse | Raw response |
body | typing.Union[SchemaFor200ResponseBodyApplicationJson, ] | |
headers | Unset | headers were not defined |
# SchemaFor200ResponseBodyApplicationJson
## Model Type Info
Input Type | Accessed Type | Description | Notes
------------ | ------------- | ------------- | -------------
dict, frozendict.frozendict, | frozendict.frozendict, | |
### Authorization
No authorization required
[[Back to top]](#__pageTop) [[Back to API list]](../../../README.md#documentation-for-api-endpoints) [[Back to Model list]](../../../README.md#documentation-for-models) [[Back to README]](../../../README.md)

View File

@@ -1,3 +1,5 @@
# coding: utf-8
# flake8: noqa
"""
@@ -9,7 +11,6 @@
Generated by: https://openapi-generator.tech
"""
__version__ = "1.0.0"
# import ApiClient

View File

@@ -1,17 +1,3 @@
# flake8: noqa
# Import all APIs into this package.
# If you have many APIs here with many many models used in each API this may
# raise a `RecursionError`.
# In order to avoid this, import only the API that you directly need like:
#
# from dynamic_servers.api.usage_api import UsageApi
#
# or import this package, but before doing it, use:
#
# import sys
# sys.setrecursionlimit(n)
# Import APIs into API package:
from dynamic_servers.api.usage_api import UsageApi
# do not import all endpoints into this module because that uses a lot of memory and stack frames
# if you need the ability to import all endpoints then import them from
# tags, paths, or path_to_api, or tag_to_api

View File

@@ -0,0 +1,20 @@
import typing_extensions
from dynamic_servers.paths import PathValues
from dynamic_servers.apis.paths.default import Default
from dynamic_servers.apis.paths.custom import Custom
PathToApi = typing_extensions.TypedDict(
'PathToApi',
{
PathValues.DEFAULT: Default,
PathValues.CUSTOM: Custom,
}
)
path_to_api = PathToApi(
{
PathValues.DEFAULT: Default,
PathValues.CUSTOM: Custom,
}
)

View File

@@ -0,0 +1,3 @@
# do not import all endpoints into this module because that uses a lot of memory and stack frames
# if you need the ability to import all endpoints from this module, import them with
# from dynamic_servers.apis.path_to_api import path_to_api

View File

@@ -0,0 +1,7 @@
from dynamic_servers.paths.custom.get import ApiForget
class Custom(
ApiForget,
):
pass

View File

@@ -0,0 +1,7 @@
from dynamic_servers.paths.default.get import ApiForget
class Default(
ApiForget,
):
pass

View File

@@ -0,0 +1,17 @@
import typing_extensions
from dynamic_servers.apis.tags import TagValues
from dynamic_servers.apis.tags.usage_api import UsageApi
TagToApi = typing_extensions.TypedDict(
'TagToApi',
{
TagValues.USAGE: UsageApi,
}
)
tag_to_api = TagToApi(
{
TagValues.USAGE: UsageApi,
}
)

View File

@@ -0,0 +1,9 @@
# do not import all endpoints into this module because that uses a lot of memory and stack frames
# if you need the ability to import all endpoints from this module, import them with
# from dynamic_servers.apis.tag_to_api import tag_to_api
import enum
class TagValues(str, enum.Enum):
USAGE = "usage"

View File

@@ -0,0 +1,25 @@
# coding: utf-8
"""
OpenAPI Extension with dynamic servers
This specification shows how to use dynamic servers. # noqa: E501
The version of the OpenAPI document: 1.0.0
Generated by: https://openapi-generator.tech
"""
from dynamic_servers.paths.custom.get import CustomServer
from dynamic_servers.paths.default.get import DefaultServer
class UsageApi(
CustomServer,
DefaultServer,
):
"""NOTE: This class is auto generated by OpenAPI Generator
Ref: https://openapi-generator.tech
Do not edit the class manually.
"""
pass

View File

@@ -1,3 +1,5 @@
# coding: utf-8
"""
OpenAPI Extension with dynamic servers
@@ -7,7 +9,6 @@
Generated by: https://openapi-generator.tech
"""
import copy
import logging
import multiprocessing
@@ -21,7 +22,8 @@ from dynamic_servers.exceptions import ApiValueError
JSON_SCHEMA_VALIDATION_KEYWORDS = {
'multipleOf', 'maximum', 'exclusiveMaximum',
'minimum', 'exclusiveMinimum', 'maxLength',
'minLength', 'pattern', 'maxItems', 'minItems'
'minLength', 'pattern', 'maxItems', 'minItems',
'uniqueItems', 'maxProperties', 'minProperties',
}
class Configuration(object):
@@ -73,8 +75,6 @@ class Configuration(object):
:param server_operation_variables: Mapping from operation ID to a mapping with
string values to replace variables in templated server configuration.
The validation of enums is performed for variables with defined enum values before.
:param ssl_ca_cert: str - the path to a file of concatenated CA certificates
in PEM format
"""
@@ -82,13 +82,11 @@ class Configuration(object):
def __init__(self, host=None,
api_key=None, api_key_prefix=None,
access_token=None,
username=None, password=None,
discard_unknown_keys=False,
disabled_client_side_validations="",
server_index=None, server_variables=None,
server_operation_index=None, server_operation_variables=None,
ssl_ca_cert=None,
):
"""Constructor
"""
@@ -107,7 +105,6 @@ class Configuration(object):
"""Temp file folder for downloading files
"""
# Authentication Settings
self.access_token = access_token
self.api_key = {}
if api_key:
self.api_key = api_key
@@ -155,7 +152,7 @@ class Configuration(object):
Set this to false to skip verifying SSL certificate when calling API
from https server.
"""
self.ssl_ca_cert = ssl_ca_cert
self.ssl_ca_cert = None
"""Set this to customize the certificate file to verify the peer.
"""
self.cert_file = None
@@ -179,9 +176,6 @@ class Configuration(object):
self.proxy = None
"""Proxy URL
"""
self.no_proxy = None
"""bypass proxy for host in the no_proxy list.
"""
self.proxy_headers = None
"""Proxy headers
"""
@@ -401,7 +395,7 @@ class Configuration(object):
"qa-petstore",
"dev-petstore"
]
},
},
'port': {
'description': "No description provided",
'default_value': "80",
@@ -409,8 +403,8 @@ class Configuration(object):
"80",
"8080"
]
}
}
}
},
{
'url': "https://localhost:8080/{version}",
@@ -424,8 +418,8 @@ class Configuration(object):
"v2",
"v3"
]
}
}
}
}
]

View File

@@ -1,3 +1,5 @@
# coding: utf-8
"""
OpenAPI Extension with dynamic servers
@@ -97,12 +99,12 @@ class ApiKeyError(OpenApiException, KeyError):
class ApiException(OpenApiException):
def __init__(self, status=None, reason=None, http_resp=None):
if http_resp:
self.status = http_resp.status
self.reason = http_resp.reason
self.body = http_resp.data
self.headers = http_resp.getheaders()
def __init__(self, status=None, reason=None, api_response: 'dynamic_servers.api_client.ApiResponse' = None):
if api_response:
self.status = api_response.response.status
self.reason = api_response.response.reason
self.body = api_response.response.data
self.headers = api_response.response.getheaders()
else:
self.status = status
self.reason = reason
@@ -111,7 +113,7 @@ class ApiException(OpenApiException):
def __str__(self):
"""Custom error messages for exception"""
error_message = "Status Code: {0}\n"\
error_message = "({0})\n"\
"Reason: {1}\n".format(self.status, self.reason)
if self.headers:
error_message += "HTTP response headers: {0}\n".format(
@@ -123,30 +125,6 @@ class ApiException(OpenApiException):
return error_message
class NotFoundException(ApiException):
def __init__(self, status=None, reason=None, http_resp=None):
super(NotFoundException, self).__init__(status, reason, http_resp)
class UnauthorizedException(ApiException):
def __init__(self, status=None, reason=None, http_resp=None):
super(UnauthorizedException, self).__init__(status, reason, http_resp)
class ForbiddenException(ApiException):
def __init__(self, status=None, reason=None, http_resp=None):
super(ForbiddenException, self).__init__(status, reason, http_resp)
class ServiceException(ApiException):
def __init__(self, status=None, reason=None, http_resp=None):
super(ServiceException, self).__init__(status, reason, http_resp)
def render_path(path_to_item):
"""Returns a string representation of a path"""
result = ""

View File

@@ -1,3 +1,5 @@
# coding: utf-8
# flake8: noqa
# import all models into this package

View File

@@ -0,0 +1,10 @@
# do not import all endpoints into this module because that uses a lot of memory and stack frames
# if you need the ability to import all endpoints from this module, import them with
# from dynamic_servers.apis.path_to_api import path_to_api
import enum
class PathValues(str, enum.Enum):
DEFAULT = "/default"
CUSTOM = "/custom"

View File

@@ -0,0 +1,7 @@
# do not import all endpoints into this module because that uses a lot of memory and stack frames
# if you need the ability to import all endpoints from this module, import them with
# from dynamic_servers.paths.custom import Api
from dynamic_servers.paths import PathValues
path = PathValues.CUSTOM

View File

@@ -0,0 +1,205 @@
# coding: utf-8
"""
Generated by: https://openapi-generator.tech
"""
from dataclasses import dataclass
import typing_extensions
import urllib3
from urllib3._collections import HTTPHeaderDict
from dynamic_servers import api_client, exceptions
from datetime import date, datetime # noqa: F401
import decimal # noqa: F401
import functools # noqa: F401
import io # noqa: F401
import re # noqa: F401
import typing # noqa: F401
import typing_extensions # noqa: F401
import uuid # noqa: F401
import frozendict # noqa: F401
from dynamic_servers import schemas # noqa: F401
from . import path
_servers = (
{
'url': "https://{server}.swagger.io:{port}/v2",
'description': "No description provided",
'variables': {
'server': {
'description': "No description provided",
'default_value': "custom-petstore",
'enum_values': [
"custom-petstore",
"custom-qa-petstore",
"custom-dev-petstore"
]
},
'port': {
'description': "No description provided",
'default_value': "8080",
'enum_values': [
"80",
"8080"
]
}
}
},
{
'url': "https://localhost:8081/{version}",
'description': "The local custom server",
'variables': {
'version': {
'description': "No description provided",
'default_value': "v2",
'enum_values': [
"v1",
"v2",
"v3"
]
}
}
},
{
'url': "https://third.example.com/{prefix}",
'description': "The local custom server",
'variables': {
'prefix': {
'description': "No description provided",
'default_value': "custom",
}
}
},
)
SchemaFor200ResponseBodyApplicationJson = schemas.DictSchema
@dataclass
class ApiResponseFor200(api_client.ApiResponse):
response: urllib3.HTTPResponse
body: typing.Union[
SchemaFor200ResponseBodyApplicationJson,
]
headers: schemas.Unset = schemas.unset
_response_for_200 = api_client.OpenApiResponse(
response_cls=ApiResponseFor200,
content={
'application/json': api_client.MediaType(
schema=SchemaFor200ResponseBodyApplicationJson),
},
)
_status_code_to_response = {
'200': _response_for_200,
}
_all_accept_content_types = (
'application/json',
)
class BaseApi(api_client.Api):
def _custom_server_oapg(
self: api_client.Api,
accept_content_types: typing.Tuple[str] = _all_accept_content_types,
host_index: typing.Optional[int] = None,
stream: bool = False,
timeout: typing.Optional[typing.Union[int, typing.Tuple]] = None,
skip_deserialization: bool = False,
) -> typing.Union[
ApiResponseFor200,
api_client.ApiResponseWithoutDeserialization
]:
"""
Use custom server
:param skip_deserialization: If true then api_response.response will be set but
api_response.body and api_response.headers will not be deserialized into schema
class instances
"""
used_path = path.value
_headers = HTTPHeaderDict()
# TODO add cookie handling
if accept_content_types:
for accept_content_type in accept_content_types:
_headers.add('Accept', accept_content_type)
host = self._get_host_oapg('custom_server', _servers, host_index)
response = self.api_client.call_api(
resource_path=used_path,
method='get'.upper(),
headers=_headers,
host=host,
stream=stream,
timeout=timeout,
)
if skip_deserialization:
api_response = api_client.ApiResponseWithoutDeserialization(response=response)
else:
response_for_status = _status_code_to_response.get(str(response.status))
if response_for_status:
api_response = response_for_status.deserialize(response, self.api_client.configuration)
else:
api_response = api_client.ApiResponseWithoutDeserialization(response=response)
if not 200 <= response.status <= 299:
raise exceptions.ApiException(api_response=api_response)
return api_response
class CustomServer(BaseApi):
# this class is used by api classes that refer to endpoints with operationId fn names
def custom_server(
self: BaseApi,
accept_content_types: typing.Tuple[str] = _all_accept_content_types,
host_index: typing.Optional[int] = None,
stream: bool = False,
timeout: typing.Optional[typing.Union[int, typing.Tuple]] = None,
skip_deserialization: bool = False,
) -> typing.Union[
ApiResponseFor200,
api_client.ApiResponseWithoutDeserialization
]:
return self._custom_server_oapg(
accept_content_types=accept_content_types,
host_index=host_index,
stream=stream,
timeout=timeout,
skip_deserialization=skip_deserialization
)
class ApiForget(BaseApi):
# this class is used by api classes that refer to endpoints by path and http method names
def get(
self: BaseApi,
accept_content_types: typing.Tuple[str] = _all_accept_content_types,
host_index: typing.Optional[int] = None,
stream: bool = False,
timeout: typing.Optional[typing.Union[int, typing.Tuple]] = None,
skip_deserialization: bool = False,
) -> typing.Union[
ApiResponseFor200,
api_client.ApiResponseWithoutDeserialization
]:
return self._custom_server_oapg(
accept_content_types=accept_content_types,
host_index=host_index,
stream=stream,
timeout=timeout,
skip_deserialization=skip_deserialization
)

View File

@@ -0,0 +1,132 @@
# coding: utf-8
"""
Generated by: https://openapi-generator.tech
"""
from dataclasses import dataclass
import typing_extensions
import urllib3
from urllib3._collections import HTTPHeaderDict
from dynamic_servers import api_client, exceptions
from datetime import date, datetime # noqa: F401
import decimal # noqa: F401
import functools # noqa: F401
import io # noqa: F401
import re # noqa: F401
import typing # noqa: F401
import typing_extensions # noqa: F401
import uuid # noqa: F401
import frozendict # noqa: F401
from dynamic_servers import schemas # noqa: F401
SchemaFor200ResponseBodyApplicationJson = schemas.DictSchema
_all_accept_content_types = (
'application/json',
)
class BaseApi(api_client.Api):
def _custom_server_oapg(
self: api_client.Api,
accept_content_types: typing.Tuple[str] = _all_accept_content_types,
host_index: typing.Optional[int] = None,
stream: bool = False,
timeout: typing.Optional[typing.Union[int, typing.Tuple]] = None,
skip_deserialization: bool = False,
) -> typing.Union[
ApiResponseFor200,
api_client.ApiResponseWithoutDeserialization
]:
"""
Use custom server
:param skip_deserialization: If true then api_response.response will be set but
api_response.body and api_response.headers will not be deserialized into schema
class instances
"""
used_path = path.value
_headers = HTTPHeaderDict()
# TODO add cookie handling
if accept_content_types:
for accept_content_type in accept_content_types:
_headers.add('Accept', accept_content_type)
host = self._get_host_oapg('custom_server', _servers, host_index)
response = self.api_client.call_api(
resource_path=used_path,
method='get'.upper(),
headers=_headers,
host=host,
stream=stream,
timeout=timeout,
)
if skip_deserialization:
api_response = api_client.ApiResponseWithoutDeserialization(response=response)
else:
response_for_status = _status_code_to_response.get(str(response.status))
if response_for_status:
api_response = response_for_status.deserialize(response, self.api_client.configuration)
else:
api_response = api_client.ApiResponseWithoutDeserialization(response=response)
if not 200 <= response.status <= 299:
raise exceptions.ApiException(api_response=api_response)
return api_response
class CustomServer(BaseApi):
# this class is used by api classes that refer to endpoints with operationId fn names
def custom_server(
self: BaseApi,
accept_content_types: typing.Tuple[str] = _all_accept_content_types,
host_index: typing.Optional[int] = None,
stream: bool = False,
timeout: typing.Optional[typing.Union[int, typing.Tuple]] = None,
skip_deserialization: bool = False,
) -> typing.Union[
ApiResponseFor200,
api_client.ApiResponseWithoutDeserialization
]:
return self._custom_server_oapg(
accept_content_types=accept_content_types,
host_index=host_index,
stream=stream,
timeout=timeout,
skip_deserialization=skip_deserialization
)
class ApiForget(BaseApi):
# this class is used by api classes that refer to endpoints by path and http method names
def get(
self: BaseApi,
accept_content_types: typing.Tuple[str] = _all_accept_content_types,
host_index: typing.Optional[int] = None,
stream: bool = False,
timeout: typing.Optional[typing.Union[int, typing.Tuple]] = None,
skip_deserialization: bool = False,
) -> typing.Union[
ApiResponseFor200,
api_client.ApiResponseWithoutDeserialization
]:
return self._custom_server_oapg(
accept_content_types=accept_content_types,
host_index=host_index,
stream=stream,
timeout=timeout,
skip_deserialization=skip_deserialization
)

View File

@@ -0,0 +1,7 @@
# do not import all endpoints into this module because that uses a lot of memory and stack frames
# if you need the ability to import all endpoints from this module, import them with
# from dynamic_servers.paths.default import Api
from dynamic_servers.paths import PathValues
path = PathValues.DEFAULT

View File

@@ -0,0 +1,147 @@
# coding: utf-8
"""
Generated by: https://openapi-generator.tech
"""
from dataclasses import dataclass
import typing_extensions
import urllib3
from urllib3._collections import HTTPHeaderDict
from dynamic_servers import api_client, exceptions
from datetime import date, datetime # noqa: F401
import decimal # noqa: F401
import functools # noqa: F401
import io # noqa: F401
import re # noqa: F401
import typing # noqa: F401
import typing_extensions # noqa: F401
import uuid # noqa: F401
import frozendict # noqa: F401
from dynamic_servers import schemas # noqa: F401
from . import path
SchemaFor200ResponseBodyApplicationJson = schemas.DictSchema
@dataclass
class ApiResponseFor200(api_client.ApiResponse):
response: urllib3.HTTPResponse
body: typing.Union[
SchemaFor200ResponseBodyApplicationJson,
]
headers: schemas.Unset = schemas.unset
_response_for_200 = api_client.OpenApiResponse(
response_cls=ApiResponseFor200,
content={
'application/json': api_client.MediaType(
schema=SchemaFor200ResponseBodyApplicationJson),
},
)
_status_code_to_response = {
'200': _response_for_200,
}
_all_accept_content_types = (
'application/json',
)
class BaseApi(api_client.Api):
def _default_server_oapg(
self: api_client.Api,
accept_content_types: typing.Tuple[str] = _all_accept_content_types,
stream: bool = False,
timeout: typing.Optional[typing.Union[int, typing.Tuple]] = None,
skip_deserialization: bool = False,
) -> typing.Union[
ApiResponseFor200,
api_client.ApiResponseWithoutDeserialization
]:
"""
Use default server
:param skip_deserialization: If true then api_response.response will be set but
api_response.body and api_response.headers will not be deserialized into schema
class instances
"""
used_path = path.value
_headers = HTTPHeaderDict()
# TODO add cookie handling
if accept_content_types:
for accept_content_type in accept_content_types:
_headers.add('Accept', accept_content_type)
response = self.api_client.call_api(
resource_path=used_path,
method='get'.upper(),
headers=_headers,
stream=stream,
timeout=timeout,
)
if skip_deserialization:
api_response = api_client.ApiResponseWithoutDeserialization(response=response)
else:
response_for_status = _status_code_to_response.get(str(response.status))
if response_for_status:
api_response = response_for_status.deserialize(response, self.api_client.configuration)
else:
api_response = api_client.ApiResponseWithoutDeserialization(response=response)
if not 200 <= response.status <= 299:
raise exceptions.ApiException(api_response=api_response)
return api_response
class DefaultServer(BaseApi):
# this class is used by api classes that refer to endpoints with operationId fn names
def default_server(
self: BaseApi,
accept_content_types: typing.Tuple[str] = _all_accept_content_types,
stream: bool = False,
timeout: typing.Optional[typing.Union[int, typing.Tuple]] = None,
skip_deserialization: bool = False,
) -> typing.Union[
ApiResponseFor200,
api_client.ApiResponseWithoutDeserialization
]:
return self._default_server_oapg(
accept_content_types=accept_content_types,
stream=stream,
timeout=timeout,
skip_deserialization=skip_deserialization
)
class ApiForget(BaseApi):
# this class is used by api classes that refer to endpoints by path and http method names
def get(
self: BaseApi,
accept_content_types: typing.Tuple[str] = _all_accept_content_types,
stream: bool = False,
timeout: typing.Optional[typing.Union[int, typing.Tuple]] = None,
skip_deserialization: bool = False,
) -> typing.Union[
ApiResponseFor200,
api_client.ApiResponseWithoutDeserialization
]:
return self._default_server_oapg(
accept_content_types=accept_content_types,
stream=stream,
timeout=timeout,
skip_deserialization=skip_deserialization
)

View File

@@ -0,0 +1,124 @@
# coding: utf-8
"""
Generated by: https://openapi-generator.tech
"""
from dataclasses import dataclass
import typing_extensions
import urllib3
from urllib3._collections import HTTPHeaderDict
from dynamic_servers import api_client, exceptions
from datetime import date, datetime # noqa: F401
import decimal # noqa: F401
import functools # noqa: F401
import io # noqa: F401
import re # noqa: F401
import typing # noqa: F401
import typing_extensions # noqa: F401
import uuid # noqa: F401
import frozendict # noqa: F401
from dynamic_servers import schemas # noqa: F401
SchemaFor200ResponseBodyApplicationJson = schemas.DictSchema
_all_accept_content_types = (
'application/json',
)
class BaseApi(api_client.Api):
def _default_server_oapg(
self: api_client.Api,
accept_content_types: typing.Tuple[str] = _all_accept_content_types,
stream: bool = False,
timeout: typing.Optional[typing.Union[int, typing.Tuple]] = None,
skip_deserialization: bool = False,
) -> typing.Union[
ApiResponseFor200,
api_client.ApiResponseWithoutDeserialization
]:
"""
Use default server
:param skip_deserialization: If true then api_response.response will be set but
api_response.body and api_response.headers will not be deserialized into schema
class instances
"""
used_path = path.value
_headers = HTTPHeaderDict()
# TODO add cookie handling
if accept_content_types:
for accept_content_type in accept_content_types:
_headers.add('Accept', accept_content_type)
response = self.api_client.call_api(
resource_path=used_path,
method='get'.upper(),
headers=_headers,
stream=stream,
timeout=timeout,
)
if skip_deserialization:
api_response = api_client.ApiResponseWithoutDeserialization(response=response)
else:
response_for_status = _status_code_to_response.get(str(response.status))
if response_for_status:
api_response = response_for_status.deserialize(response, self.api_client.configuration)
else:
api_response = api_client.ApiResponseWithoutDeserialization(response=response)
if not 200 <= response.status <= 299:
raise exceptions.ApiException(api_response=api_response)
return api_response
class DefaultServer(BaseApi):
# this class is used by api classes that refer to endpoints with operationId fn names
def default_server(
self: BaseApi,
accept_content_types: typing.Tuple[str] = _all_accept_content_types,
stream: bool = False,
timeout: typing.Optional[typing.Union[int, typing.Tuple]] = None,
skip_deserialization: bool = False,
) -> typing.Union[
ApiResponseFor200,
api_client.ApiResponseWithoutDeserialization
]:
return self._default_server_oapg(
accept_content_types=accept_content_types,
stream=stream,
timeout=timeout,
skip_deserialization=skip_deserialization
)
class ApiForget(BaseApi):
# this class is used by api classes that refer to endpoints by path and http method names
def get(
self: BaseApi,
accept_content_types: typing.Tuple[str] = _all_accept_content_types,
stream: bool = False,
timeout: typing.Optional[typing.Union[int, typing.Tuple]] = None,
skip_deserialization: bool = False,
) -> typing.Union[
ApiResponseFor200,
api_client.ApiResponseWithoutDeserialization
]:
return self._default_server_oapg(
accept_content_types=accept_content_types,
stream=stream,
timeout=timeout,
skip_deserialization=skip_deserialization
)

View File

@@ -1,3 +1,5 @@
# coding: utf-8
"""
OpenAPI Extension with dynamic servers
@@ -7,41 +9,21 @@
Generated by: https://openapi-generator.tech
"""
import io
import json
import logging
import re
import ssl
from urllib.parse import urlencode
from urllib.parse import urlparse
from urllib.request import proxy_bypass_environment
import urllib3
import ipaddress
import typing
from dynamic_servers.exceptions import ApiException, UnauthorizedException, ForbiddenException, NotFoundException, ServiceException, ApiValueError
import certifi
import urllib3
from urllib3._collections import HTTPHeaderDict
from dynamic_servers.exceptions import ApiException, ApiValueError
logger = logging.getLogger(__name__)
class RESTResponse(io.IOBase):
def __init__(self, resp):
self.urllib3_response = resp
self.status = resp.status
self.reason = resp.reason
self.data = resp.data
def getheaders(self):
"""Returns a dictionary of the response headers."""
return self.urllib3_response.getheaders()
def getheader(self, name, default=None):
"""Returns a given response header."""
return self.urllib3_response.getheader(name, default)
class RESTClientObject(object):
def __init__(self, configuration, pools_size=4, maxsize=None):
@@ -57,6 +39,13 @@ class RESTClientObject(object):
else:
cert_reqs = ssl.CERT_NONE
# ca_certs
if configuration.ssl_ca_cert:
ca_certs = configuration.ssl_ca_cert
else:
# if not set certificate file, use Mozilla's root certificates.
ca_certs = certifi.where()
addition_pool_args = {}
if configuration.assert_hostname is not None:
addition_pool_args['assert_hostname'] = configuration.assert_hostname # noqa: E501
@@ -74,13 +63,12 @@ class RESTClientObject(object):
maxsize = 4
# https pool manager
if configuration.proxy and not should_bypass_proxies(
configuration.host, no_proxy=configuration.no_proxy or ''):
if configuration.proxy:
self.pool_manager = urllib3.ProxyManager(
num_pools=pools_size,
maxsize=maxsize,
cert_reqs=cert_reqs,
ca_certs=configuration.ssl_ca_cert,
ca_certs=ca_certs,
cert_file=configuration.cert_file,
key_file=configuration.key_file,
proxy_url=configuration.proxy,
@@ -92,79 +80,75 @@ class RESTClientObject(object):
num_pools=pools_size,
maxsize=maxsize,
cert_reqs=cert_reqs,
ca_certs=configuration.ssl_ca_cert,
ca_certs=ca_certs,
cert_file=configuration.cert_file,
key_file=configuration.key_file,
**addition_pool_args
)
def request(self, method, url, query_params=None, headers=None,
body=None, post_params=None, _preload_content=True,
_request_timeout=None):
def request(
self,
method: str,
url: str,
headers: typing.Optional[HTTPHeaderDict] = None,
fields: typing.Optional[typing.Tuple[typing.Tuple[str, typing.Any], ...]] = None,
body: typing.Optional[typing.Union[str, bytes]] = None,
stream: bool = False,
timeout: typing.Optional[typing.Union[int, typing.Tuple]] = None,
) -> urllib3.HTTPResponse:
"""Perform requests.
:param method: http request method
:param url: http request url
:param query_params: query parameters in the url
:param headers: http request headers
:param body: request json body, for `application/json`
:param post_params: request post parameters,
`application/x-www-form-urlencoded`
and `multipart/form-data`
:param _preload_content: if False, the urllib3.HTTPResponse object will
be returned without reading/decoding response
data. Default is True.
:param _request_timeout: timeout setting for this request. If one
number provided, it will be total request
timeout. It can also be a pair (tuple) of
(connection, read) timeouts.
:param body: request body, for other types
:param fields: request parameters for
`application/x-www-form-urlencoded`
or `multipart/form-data`
:param stream: if True, the urllib3.HTTPResponse object will
be returned without reading/decoding response
data. Default is False.
:param timeout: timeout setting for this request. If one
number provided, it will be total request
timeout. It can also be a pair (tuple) of
(connection, read) timeouts.
"""
method = method.upper()
assert method in ['GET', 'HEAD', 'DELETE', 'POST', 'PUT',
'PATCH', 'OPTIONS']
if post_params and body:
if fields and body:
raise ApiValueError(
"body parameter cannot be used with post_params parameter."
"body parameter cannot be used with fields parameter."
)
post_params = post_params or {}
fields = fields or {}
headers = headers or {}
timeout = None
if _request_timeout:
if isinstance(_request_timeout, (int, float)): # noqa: E501,F821
timeout = urllib3.Timeout(total=_request_timeout)
elif (isinstance(_request_timeout, tuple) and
len(_request_timeout) == 2):
timeout = urllib3.Timeout(
connect=_request_timeout[0], read=_request_timeout[1])
if timeout:
if isinstance(timeout, (int, float)): # noqa: E501,F821
timeout = urllib3.Timeout(total=timeout)
elif (isinstance(timeout, tuple) and
len(timeout) == 2):
timeout = urllib3.Timeout(connect=timeout[0], read=timeout[1])
try:
# For `POST`, `PUT`, `PATCH`, `OPTIONS`, `DELETE`
if method in ['POST', 'PUT', 'PATCH', 'OPTIONS', 'DELETE']:
# Only set a default Content-Type for POST, PUT, PATCH and OPTIONS requests
if (method != 'DELETE') and ('Content-Type' not in headers):
headers['Content-Type'] = 'application/json'
if query_params:
url += '?' + urlencode(query_params)
if ('Content-Type' not in headers) or (re.search('json',
headers['Content-Type'], re.IGNORECASE)):
request_body = None
if body is not None:
request_body = json.dumps(body)
if 'Content-Type' not in headers and body is None:
r = self.pool_manager.request(
method, url,
body=request_body,
preload_content=_preload_content,
method,
url,
preload_content=not stream,
timeout=timeout,
headers=headers)
headers=headers
)
elif headers['Content-Type'] == 'application/x-www-form-urlencoded': # noqa: E501
r = self.pool_manager.request(
method, url,
fields=post_params,
fields=fields,
encode_multipart=False,
preload_content=_preload_content,
preload_content=not stream,
timeout=timeout,
headers=headers)
elif headers['Content-Type'] == 'multipart/form-data':
@@ -174,9 +158,9 @@ class RESTClientObject(object):
del headers['Content-Type']
r = self.pool_manager.request(
method, url,
fields=post_params,
fields=fields,
encode_multipart=True,
preload_content=_preload_content,
preload_content=not stream,
timeout=timeout,
headers=headers)
# Pass a `string` parameter directly in the body to support
@@ -187,7 +171,7 @@ class RESTClientObject(object):
r = self.pool_manager.request(
method, url,
body=request_body,
preload_content=_preload_content,
preload_content=not stream,
timeout=timeout,
headers=headers)
else:
@@ -199,154 +183,71 @@ class RESTClientObject(object):
# For `GET`, `HEAD`
else:
r = self.pool_manager.request(method, url,
fields=query_params,
preload_content=_preload_content,
preload_content=not stream,
timeout=timeout,
headers=headers)
except urllib3.exceptions.SSLError as e:
msg = "{0}\n{1}".format(type(e).__name__, str(e))
raise ApiException(status=0, reason=msg)
if _preload_content:
r = RESTResponse(r)
if not stream:
# log response body
logger.debug("response body: %s", r.data)
if not 200 <= r.status <= 299:
if r.status == 401:
raise UnauthorizedException(http_resp=r)
if r.status == 403:
raise ForbiddenException(http_resp=r)
if r.status == 404:
raise NotFoundException(http_resp=r)
if 500 <= r.status <= 599:
raise ServiceException(http_resp=r)
raise ApiException(http_resp=r)
return r
def GET(self, url, headers=None, query_params=None, _preload_content=True,
_request_timeout=None):
def GET(self, url, headers=None, stream=False,
timeout=None, fields=None) -> urllib3.HTTPResponse:
return self.request("GET", url,
headers=headers,
_preload_content=_preload_content,
_request_timeout=_request_timeout,
query_params=query_params)
stream=stream,
timeout=timeout,
fields=fields)
def HEAD(self, url, headers=None, query_params=None, _preload_content=True,
_request_timeout=None):
def HEAD(self, url, headers=None, stream=False,
timeout=None, fields=None) -> urllib3.HTTPResponse:
return self.request("HEAD", url,
headers=headers,
_preload_content=_preload_content,
_request_timeout=_request_timeout,
query_params=query_params)
stream=stream,
timeout=timeout,
fields=fields)
def OPTIONS(self, url, headers=None, query_params=None, post_params=None,
body=None, _preload_content=True, _request_timeout=None):
def OPTIONS(self, url, headers=None,
body=None, stream=False, timeout=None, fields=None) -> urllib3.HTTPResponse:
return self.request("OPTIONS", url,
headers=headers,
query_params=query_params,
post_params=post_params,
_preload_content=_preload_content,
_request_timeout=_request_timeout,
body=body)
stream=stream,
timeout=timeout,
body=body, fields=fields)
def DELETE(self, url, headers=None, query_params=None, body=None,
_preload_content=True, _request_timeout=None):
def DELETE(self, url, headers=None, body=None,
stream=False, timeout=None, fields=None) -> urllib3.HTTPResponse:
return self.request("DELETE", url,
headers=headers,
query_params=query_params,
_preload_content=_preload_content,
_request_timeout=_request_timeout,
body=body)
stream=stream,
timeout=timeout,
body=body, fields=fields)
def POST(self, url, headers=None, query_params=None, post_params=None,
body=None, _preload_content=True, _request_timeout=None):
def POST(self, url, headers=None,
body=None, stream=False, timeout=None, fields=None) -> urllib3.HTTPResponse:
return self.request("POST", url,
headers=headers,
query_params=query_params,
post_params=post_params,
_preload_content=_preload_content,
_request_timeout=_request_timeout,
body=body)
stream=stream,
timeout=timeout,
body=body, fields=fields)
def PUT(self, url, headers=None, query_params=None, post_params=None,
body=None, _preload_content=True, _request_timeout=None):
def PUT(self, url, headers=None,
body=None, stream=False, timeout=None, fields=None) -> urllib3.HTTPResponse:
return self.request("PUT", url,
headers=headers,
query_params=query_params,
post_params=post_params,
_preload_content=_preload_content,
_request_timeout=_request_timeout,
body=body)
stream=stream,
timeout=timeout,
body=body, fields=fields)
def PATCH(self, url, headers=None, query_params=None, post_params=None,
body=None, _preload_content=True, _request_timeout=None):
def PATCH(self, url, headers=None,
body=None, stream=False, timeout=None, fields=None) -> urllib3.HTTPResponse:
return self.request("PATCH", url,
headers=headers,
query_params=query_params,
post_params=post_params,
_preload_content=_preload_content,
_request_timeout=_request_timeout,
body=body)
# end of class RESTClientObject
def is_ipv4(target):
""" Test if IPv4 address or not
"""
try:
chk = ipaddress.IPv4Address(target)
return True
except ipaddress.AddressValueError:
return False
def in_ipv4net(target, net):
""" Test if target belongs to given IPv4 network
"""
try:
nw = ipaddress.IPv4Network(net)
ip = ipaddress.IPv4Address(target)
if ip in nw:
return True
return False
except ipaddress.AddressValueError:
return False
except ipaddress.NetmaskValueError:
return False
def should_bypass_proxies(url, no_proxy=None):
""" Yet another requests.should_bypass_proxies
Test if proxies should not be used for a particular url.
"""
parsed = urlparse(url)
# special cases
if parsed.hostname in [None, '']:
return True
# special cases
if no_proxy in [None, '']:
return False
if no_proxy == '*':
return True
no_proxy = no_proxy.lower().replace(' ', '');
entries = (
host for host in no_proxy.split(',') if host
)
if is_ipv4(parsed.hostname):
for item in entries:
if in_ipv4net(parsed.hostname, item):
return True
return proxy_bypass_environment(parsed.hostname, {'no': no_proxy})
stream=stream,
timeout=timeout,
body=body, fields=fields)

View File

@@ -1,7 +1,7 @@
#!/bin/sh
# ref: https://help.github.com/articles/adding-an-existing-project-to-github-using-the-command-line/
#
# Usage example: /bin/sh ./git_push.sh wing328 openapi-petstore-perl "minor update" "gitlab.com"
# Usage example: /bin/sh ./git_push.sh wing328 openapi-pestore-perl "minor update" "gitlab.com"
git_user_id=$1
git_repo_id=$2
@@ -38,14 +38,14 @@ git add .
git commit -m "$release_note"
# Sets the new remote
git_remote=$(git remote)
git_remote=`git remote`
if [ "$git_remote" = "" ]; then # git remote not defined
if [ "$GIT_TOKEN" = "" ]; then
echo "[INFO] \$GIT_TOKEN (environment variable) is not set. Using the git credential in your environment."
git remote add origin https://${git_host}/${git_user_id}/${git_repo_id}.git
else
git remote add origin https://${git_user_id}:"${GIT_TOKEN}"@${git_host}/${git_user_id}/${git_repo_id}.git
git remote add origin https://${git_user_id}:${GIT_TOKEN}@${git_host}/${git_user_id}/${git_repo_id}.git
fi
fi
@@ -55,3 +55,4 @@ git pull origin master
# Pushes (Forces) the changes in the local repository up to the remote repository
echo "Git pushing to https://${git_host}/${git_user_id}/${git_repo_id}.git"
git push origin master 2>&1 | grep -v 'To https'

View File

@@ -1,3 +1,5 @@
certifi >= 14.05.14
frozendict >= 2.0.3
python_dateutil >= 2.5.3
setuptools >= 21.0.0
urllib3 >= 1.25.3
urllib3 >= 1.15.1

View File

@@ -1,3 +1,5 @@
# coding: utf-8
"""
OpenAPI Extension with dynamic servers
@@ -7,7 +9,6 @@
Generated by: https://openapi-generator.tech
"""
from setuptools import setup, find_packages # noqa: H301
NAME = "dynamic-servers"
@@ -20,8 +21,11 @@ VERSION = "1.0.0"
# http://pypi.python.org/pypi/setuptools
REQUIRES = [
"urllib3 >= 1.25.3",
"urllib3 >= 1.15",
"certifi",
"python-dateutil",
"frozendict >= 2.0.3",
"typing_extensions",
]
setup(
@@ -32,7 +36,7 @@ setup(
author_email="team@openapitools.org",
url="",
keywords=["OpenAPI", "OpenAPI-Generator", "OpenAPI Extension with dynamic servers"],
python_requires=">=3.6",
python_requires=">=3.7",
install_requires=REQUIRES,
packages=find_packages(exclude=["test", "tests"]),
include_package_data=True,

View File

@@ -1 +1,3 @@
pytest~=4.6.7 # needed for python 3.4
pytest-cov>=2.8.1
pytest-randomly==1.2.3 # needed for python 3.4

View File

@@ -0,0 +1,68 @@
import json
import typing
import urllib3
from urllib3._collections import HTTPHeaderDict
class ApiTestMixin:
json_content_type = 'application/json'
user_agent = 'OpenAPI-Generator/1.0.0/python'
@classmethod
def assert_pool_manager_request_called_with(
cls,
mock_request,
url: str,
method: str = 'POST',
body: typing.Optional[bytes] = None,
content_type: typing.Optional[str] = None,
accept_content_type: typing.Optional[str] = None,
stream: bool = False,
):
headers = {
'User-Agent': cls.user_agent
}
if accept_content_type:
headers['Accept'] = accept_content_type
if content_type:
headers['Content-Type'] = content_type
kwargs = dict(
headers=HTTPHeaderDict(headers),
preload_content=not stream,
timeout=None,
)
if content_type and method != 'GET':
kwargs['body'] = body
mock_request.assert_called_with(
method,
url,
**kwargs
)
@staticmethod
def headers_for_content_type(content_type: str) -> typing.Dict[str, str]:
return {'content-type': content_type}
@classmethod
def response(
cls,
body: typing.Union[str, bytes],
status: int = 200,
content_type: str = json_content_type,
headers: typing.Optional[typing.Dict[str, str]] = None,
preload_content: bool = True
) -> urllib3.HTTPResponse:
if headers is None:
headers = {}
headers.update(cls.headers_for_content_type(content_type))
return urllib3.HTTPResponse(
body,
headers=headers,
status=status,
preload_content=preload_content
)
@staticmethod
def json_bytes(in_data: typing.Any) -> bytes:
return json.dumps(in_data, separators=(",", ":"), ensure_ascii=False).encode('utf-8')

View File

@@ -0,0 +1,41 @@
# coding: utf-8
"""
Generated by: https://openapi-generator.tech
"""
import unittest
from unittest.mock import patch
import urllib3
import dynamic_servers
from dynamic_servers.paths.custom import get # noqa: E501
from dynamic_servers import configuration, schemas, api_client
from .. import ApiTestMixin
class TestCustom(ApiTestMixin, unittest.TestCase):
"""
Custom unit test stubs
Use custom server # noqa: E501
"""
_configuration = configuration.Configuration()
def setUp(self):
used_api_client = api_client.ApiClient(configuration=self._configuration)
self.api = get.ApiForget(api_client=used_api_client) # noqa: E501
def tearDown(self):
pass
response_status = 200
if __name__ == '__main__':
unittest.main()

View File

@@ -0,0 +1,41 @@
# coding: utf-8
"""
Generated by: https://openapi-generator.tech
"""
import unittest
from unittest.mock import patch
import urllib3
import dynamic_servers
from dynamic_servers.paths.default import get # noqa: E501
from dynamic_servers import configuration, schemas, api_client
from .. import ApiTestMixin
class TestDefault(ApiTestMixin, unittest.TestCase):
"""
Default unit test stubs
Use default server # noqa: E501
"""
_configuration = configuration.Configuration()
def setUp(self):
used_api_client = api_client.ApiClient(configuration=self._configuration)
self.api = get.ApiForget(api_client=used_api_client) # noqa: E501
def tearDown(self):
pass
response_status = 200
if __name__ == '__main__':
unittest.main()

View File

@@ -1,7 +1,8 @@
[tox]
envlist = py3
envlist = py37
[testenv]
passenv = PYTHON_VERSION
deps=-r{toxinidir}/requirements.txt
-r{toxinidir}/test-requirements.txt