Pulp currently provides python, ruby, typescript client bindings.
We depended on:
The bindings are generated from the JSON OpenAPI schema on this endpoint:
/pulp/api/v3/docs/api.json?bindings&plugin=galaxy_ng
with the following script: https://github.com/pulp/pulp-openapi-generator/blob/master/generate.sh
The following OpenAPI schema:
"/api/galaxy/content/{path}/v3/artifacts/collections/": {
"post": {
"operationId": "create",
"description": "Create an artifact and trigger an asynchronous task to create Collection content from it.",
"summary": "Upload a collection",
"parameters": [
{
"in": "path",
"name": "path",
"schema": {
"type": "string"
},
"required": true
}
],
"tags": [
"Pulp_Ansible: Artifacts Collections V3"
],
"requestBody": {
"content": {
"multipart/form-data": {
"schema": {
"$ref": "#/components/schemas/CollectionUploadWithDownloadUrl"
}
},
"application/x-www-form-urlencoded": {
"schema": {
"$ref": "#/components/schemas/CollectionUploadWithDownloadUrl"
}
}
},
"required": true
},
"security": [
{
"cookieAuth": []
},
{
"tokenAuth": []
},
{
"basicAuth": []
}
],
"responses": {
"202": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/AsyncOperationResponse"
}
}
},
"description": ""
}
}
}
}
when converted to python bindings, would become:
class PulpAnsibleArtifactsCollectionsV3Api(object):
"""NOTE: This class is auto generated by OpenAPI Generator
Ref: https://openapi-generator.tech
Do not edit the class manually.
"""
def __init__(self, api_client=None):
if api_client is None:
api_client = ApiClient()
self.api_client = api_client
def create(self, path, file, **kwargs): # noqa: E501
"""Upload a collection # noqa: E501
Create an artifact and trigger an asynchronous task to create Collection content from it. # noqa: E501
This method makes a synchronous HTTP request by default. To make an
asynchronous HTTP request, please pass async_req=True
>>> thread = api.create(path, file, async_req=True)
>>> result = thread.get()
:param async_req bool: execute request asynchronously
:param str path: (required)
:param file file: (required)
:param str sha256:
: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.
:return: AsyncOperationResponse
If the method is called asynchronously,
returns the request thread.
"""
kwargs['_return_http_data_only'] = True
return self.create_with_http_info(path, file, **kwargs) # noqa: E501
def create_with_http_info(self, path, file, **kwargs): # noqa: E501
"""Upload a collection # noqa: E501
Create an artifact and trigger an asynchronous task to create Collection content from it. # noqa: E501
This method makes a synchronous HTTP request by default. To make an
asynchronous HTTP request, please pass async_req=True
>>> thread = api.create_with_http_info(path, file, async_req=True)
>>> result = thread.get()
:param async_req bool: execute request asynchronously
:param str path: (required)
:param file file: (required)
:param str sha256:
:param _return_http_data_only: response data without head status code
and headers
: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.
:return: tuple(AsyncOperationResponse, status_code(int), headers(HTTPHeaderDict))
If the method is called asynchronously,
returns the request thread.
"""
local_var_params = locals()
all_params = [
'path',
'file',
'sha256'
]
all_params.extend(
[
'async_req',
'_return_http_data_only',
'_preload_content',
'_request_timeout'
]
)
for key, val in six.iteritems(local_var_params['kwargs']):
if key not in all_params:
raise ApiTypeError(
"Got an unexpected keyword argument '%s'"
" to method create" % key
)
local_var_params[key] = val
del local_var_params['kwargs']
# verify the required parameter 'path' is set
if self.api_client.client_side_validation and ('path' not in local_var_params or # noqa: E501
local_var_params['path'] is None): # noqa: E501
raise ApiValueError("Missing the required parameter `path` when calling `create`") # noqa: E501
# verify the required parameter 'file' is set
if self.api_client.client_side_validation and ('file' not in local_var_params or # noqa: E501
local_var_params['file'] is None): # noqa: E501
raise ApiValueError("Missing the required parameter `file` when calling `create`") # noqa: E501
collection_formats = {}
path_params = {}
if 'path' in local_var_params:
path_params['path'] = local_var_params['path'] # noqa: E501
query_params = []
header_params = {}
form_params = []
local_var_files = {}
if 'file' in local_var_params:
local_var_files['file'] = local_var_params['file'] # noqa: E501
if 'sha256' in local_var_params:
form_params.append(('sha256', local_var_params['sha256'])) # noqa: E501
body_params = None
# HTTP header `Accept`
header_params['Accept'] = self.api_client.select_header_accept(
['application/json']) # noqa: E501
# HTTP header `Content-Type`
header_params['Content-Type'] = self.api_client.select_header_content_type( # noqa: E501
['multipart/form-data', 'application/x-www-form-urlencoded']) # noqa: E501
# Authentication setting
auth_settings = ['basicAuth', 'cookieAuth', 'tokenAuth'] # noqa: E501
return self.api_client.call_api(
'/api/galaxy/content/{path}/v3/artifacts/collections/', 'POST',
path_params,
query_params,
header_params,
body=body_params,
post_params=form_params,
files=local_var_files,
response_type='AsyncOperationResponse', # noqa: E501
auth_settings=auth_settings,
async_req=local_var_params.get('async_req'),
_return_http_data_only=local_var_params.get('_return_http_data_only'), # noqa: E501
_preload_content=local_var_params.get('_preload_content', True),
_request_timeout=local_var_params.get('_request_timeout'),
collection_formats=collection_formats)
get -> read
post -> create
put -> update
patch -> partial_update
delete -> delete
"Pulp_Ansible: Artifacts Collections V3" -> PulpAnsibleArtifactsCollectionsV3Api
Note: Generally the OpenAPI tag is generated by: URL path (/my/path/to/content -> My Path to Content), but it can be the endpoint pieces or the view name: https://github.com/pulp/pulpcore/blob/master/pulpcore/openapi/init.py#L40-L67
Note 2: You can specify the OpenAPI tag name at your view: https://docs.pulpproject.org/pulpcore/plugins/reference/how-to-doc-api.html#openapi-tags
We are using the following drf-spectacular settings: https://github.com/pulp/pulpcore/blob/master/pulpcore/app/settings.py#L264-L285
And we "patch" drf-spectacular here: https://github.com/pulp/pulpcore/blob/master/pulpcore/openapi/init.py
drf-spectacular inspects every view and its serializer and model to provide a proper OpenAPI schema.