Skip to content

Commit

Permalink
[Python][Client] pure library client package (OpenAPITools#470)
Browse files Browse the repository at this point in the history
* Python client pure library package

* check onlyPackage CLI option

* run /bin/python-petstore.sh, update the python samples for CI

* onlyPackage local variable instead of classp property

* fix CI: __future__ absolute_import must be first in file

* update samples

* generateSourceCodeOnly

* updated samples
  • Loading branch information
Matthieu Berthomé authored and wing328 committed Jul 16, 2018
1 parent 537132a commit 9a136ef
Show file tree
Hide file tree
Showing 21 changed files with 223 additions and 140 deletions.
Empty file modified bin/windows/typescript-node-petstore-with-npm.bat
100644 → 100755
Empty file.
Empty file modified bin/windows/typescript-node-petstore.bat
100644 → 100755
Empty file.
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,9 @@ public static enum ENUM_PROPERTY_NAMING_TYPE {camelCase, PascalCase, snake_case,
public static final String EXCLUDE_TESTS = "excludeTests";
public static final String EXCLUDE_TESTS_DESC = "Specifies that no tests are to be generated.";

public static final String SOURCECODEONLY_GENERATION = "generateSourceCodeOnly";
public static final String SOURCECODEONLY_GENERATION_DESC = "Specifies that only a library source code is to be generated.";

// Not user-configurable. System provided for use in templates.

public static final String GENERATE_APIS = "generateApis";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,8 @@ public PythonClientCodegen() {
CodegenConstants.SORT_PARAMS_BY_REQUIRED_FLAG_DESC).defaultValue(Boolean.TRUE.toString()));
cliOptions.add(new CliOption(CodegenConstants.HIDE_GENERATION_TIMESTAMP, CodegenConstants.HIDE_GENERATION_TIMESTAMP_DESC)
.defaultValue(Boolean.TRUE.toString()));
cliOptions.add(new CliOption(CodegenConstants.SOURCECODEONLY_GENERATION, CodegenConstants.SOURCECODEONLY_GENERATION_DESC)
.defaultValue(Boolean.FALSE.toString()));

supportedLibraries.put("urllib3", "urllib3-based client");
supportedLibraries.put("asyncio", "Asyncio-based client (python 3.5+)");
Expand Down Expand Up @@ -198,10 +200,22 @@ public void processOpts() {
setPackageVersion("1.0.0");
}

Boolean generateSourceCodeOnly = false;
if (additionalProperties.containsKey(CodegenConstants.SOURCECODEONLY_GENERATION)) {
generateSourceCodeOnly = true;
}

additionalProperties.put(CodegenConstants.PROJECT_NAME, projectName);
additionalProperties.put(CodegenConstants.PACKAGE_NAME, packageName);
additionalProperties.put(CodegenConstants.PACKAGE_VERSION, packageVersion);

if (generateSourceCodeOnly) {
// tests in <package>/test
testFolder = packageName + File.separatorChar + testFolder;
// api/model docs in <package>/docs
apiDocPath = packageName + File.separatorChar + apiDocPath;
modelDocPath = packageName + File.separatorChar + modelDocPath;
}
// make api and model doc path available in mustache template
additionalProperties.put("apiDocPath", apiDocPath);
additionalProperties.put("modelDocPath", modelDocPath);
Expand All @@ -210,12 +224,24 @@ public void processOpts() {
setPackageUrl((String) additionalProperties.get(PACKAGE_URL));
}

supportingFiles.add(new SupportingFile("README.mustache", "", "README.md"));
String readmePath ="README.md";
String readmeTemplate = "README.mustache";
if (generateSourceCodeOnly) {
readmePath = packageName + "_" + readmePath;
readmeTemplate = "README_onlypackage.mustache";
}
supportingFiles.add(new SupportingFile(readmeTemplate, "", readmePath));

supportingFiles.add(new SupportingFile("tox.mustache", "", "tox.ini"));
supportingFiles.add(new SupportingFile("test-requirements.mustache", "", "test-requirements.txt"));
supportingFiles.add(new SupportingFile("requirements.mustache", "", "requirements.txt"));
if (!generateSourceCodeOnly){
supportingFiles.add(new SupportingFile("tox.mustache", "", "tox.ini"));
supportingFiles.add(new SupportingFile("test-requirements.mustache", "", "test-requirements.txt"));
supportingFiles.add(new SupportingFile("requirements.mustache", "", "requirements.txt"));

supportingFiles.add(new SupportingFile("git_push.sh.mustache", "", "git_push.sh"));
supportingFiles.add(new SupportingFile("gitignore.mustache", "", ".gitignore"));
supportingFiles.add(new SupportingFile("travis.mustache", "", ".travis.yml"));
supportingFiles.add(new SupportingFile("setup.mustache", "", "setup.py"));
}
supportingFiles.add(new SupportingFile("configuration.mustache", packageName, "configuration.py"));
supportingFiles.add(new SupportingFile("__init__package.mustache", packageName, "__init__.py"));
supportingFiles.add(new SupportingFile("__init__model.mustache", packageName + File.separatorChar + modelPackage, "__init__.py"));
Expand All @@ -224,10 +250,7 @@ public void processOpts() {
if (Boolean.FALSE.equals(excludeTests)) {
supportingFiles.add(new SupportingFile("__init__test.mustache", testFolder, "__init__.py"));
}
supportingFiles.add(new SupportingFile("git_push.sh.mustache", "", "git_push.sh"));
supportingFiles.add(new SupportingFile("gitignore.mustache", "", ".gitignore"));
supportingFiles.add(new SupportingFile("travis.mustache", "", ".travis.yml"));
supportingFiles.add(new SupportingFile("setup.mustache", "", "setup.py"));

supportingFiles.add(new SupportingFile("api_client.mustache", packageName, "api_client.py"));

if ("asyncio".equals(getLibrary())) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,78 +52,4 @@ import {{{packageName}}}

Please follow the [installation procedure](#installation--usage) and then run the following:

```python
from __future__ import print_function
import time
import {{{packageName}}}
from {{{packageName}}}.rest import ApiException
from pprint import pprint
{{#apiInfo}}{{#apis}}{{#-first}}{{#operations}}{{#operation}}{{#-first}}{{#hasAuthMethods}}{{#authMethods}}{{#isBasic}}
# Configure HTTP basic authorization: {{{name}}}
configuration = {{{packageName}}}.Configuration()
configuration.username = 'YOUR_USERNAME'
configuration.password = 'YOUR_PASSWORD'{{/isBasic}}{{#isApiKey}}
# Configure API key authorization: {{{name}}}
configuration = {{{packageName}}}.Configuration()
configuration.api_key['{{{keyParamName}}}'] = 'YOUR_API_KEY'
# Uncomment below to setup prefix (e.g. Bearer) for API key, if needed
# configuration.api_key_prefix['{{{keyParamName}}}'] = 'Bearer'{{/isApiKey}}{{#isOAuth}}
# Configure OAuth2 access token for authorization: {{{name}}}
configuration = {{{packageName}}}.Configuration()
configuration.access_token = 'YOUR_ACCESS_TOKEN'{{/isOAuth}}{{/authMethods}}
{{/hasAuthMethods}}

# create an instance of the API class
api_instance = {{{packageName}}}.{{{classname}}}({{{packageName}}}.ApiClient(configuration))
{{#allParams}}{{paramName}} = {{{example}}} # {{{dataType}}} | {{{description}}}{{^required}} (optional){{/required}}{{#defaultValue}} (default to {{{.}}}){{/defaultValue}}
{{/allParams}}

try:
{{#summary}} # {{{.}}}
{{/summary}} {{#returnType}}api_response = {{/returnType}}api_instance.{{{operationId}}}({{#allParams}}{{#required}}{{paramName}}{{/required}}{{^required}}{{paramName}}={{paramName}}{{/required}}{{#hasMore}}, {{/hasMore}}{{/allParams}}){{#returnType}}
pprint(api_response){{/returnType}}
except ApiException as e:
print("Exception when calling {{classname}}->{{operationId}}: %s\n" % e)
{{/-first}}{{/operation}}{{/operations}}{{/-first}}{{/apis}}{{/apiInfo}}
```

## Documentation for API Endpoints

All URIs are relative to *{{basePath}}*

Class | Method | HTTP request | Description
------------ | ------------- | ------------- | -------------
{{#apiInfo}}{{#apis}}{{#operations}}{{#operation}}*{{classname}}* | [**{{operationId}}**]({{apiDocPath}}{{classname}}.md#{{operationIdLowerCase}}) | **{{httpMethod}}** {{path}} | {{#summary}}{{summary}}{{/summary}}
{{/operation}}{{/operations}}{{/apis}}{{/apiInfo}}

## Documentation For Models

{{#models}}{{#model}} - [{{{classname}}}]({{modelDocPath}}{{{classname}}}.md)
{{/model}}{{/models}}

## Documentation For Authorization

{{^authMethods}} All endpoints do not require authorization.
{{/authMethods}}{{#authMethods}}{{#last}} Authentication schemes defined for the API:{{/last}}{{/authMethods}}
{{#authMethods}}## {{{name}}}

{{#isApiKey}}- **Type**: API key
- **API key parameter name**: {{{keyParamName}}}
- **Location**: {{#isKeyInQuery}}URL query string{{/isKeyInQuery}}{{#isKeyInHeader}}HTTP header{{/isKeyInHeader}}
{{/isApiKey}}
{{#isBasic}}- **Type**: HTTP basic authentication
{{/isBasic}}
{{#isOAuth}}- **Type**: OAuth
- **Flow**: {{{flow}}}
- **Authorization URL**: {{{authorizationUrl}}}
- **Scopes**: {{^scopes}}N/A{{/scopes}}
{{#scopes}} - **{{{scope}}}**: {{{description}}}
{{/scopes}}
{{/isOAuth}}

{{/authMethods}}

## Author

{{#apiInfo}}{{#apis}}{{^hasMore}}{{infoEmail}}
{{/hasMore}}{{/apis}}{{/apiInfo}}
{{> common_README }}
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
# {{{projectName}}}
{{#appDescription}}
{{{appDescription}}}
{{/appDescription}}

The `{{packageName}}` package is automatically generated by the [OpenAPI Generator](https://openapi-generator.tech) project:

- API version: {{appVersion}}
- Package version: {{packageVersion}}
{{^hideGenerationTimestamp}}
- Build date: {{generatedDate}}
{{/hideGenerationTimestamp}}
- Build package: {{generatorClass}}
{{#infoUrl}}
For more information, please visit [{{{infoUrl}}}]({{{infoUrl}}})
{{/infoUrl}}

## Requirements.

Python 2.7 and 3.4+

## Installation & Usage

This python library package is generated without supporting files like setup.py or requirements files

To be able to use it, you will need these dependencies in your own package that uses this library:

* urllib3 >= 1.15
* six >= 1.10
* certifi
* python-dateutil
{{#asyncio}}
* aiohttp
{{/asyncio}}
{{#tornado}}
* tornado>=4.2,<5
{{/tornado}}

## Getting Started

In your own code, to use this library to connect and interact with {{{projectName}}},
you can run the following:

{{> common_README }}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@

from __future__ import absolute_import

__version__ = "{{packageVersion}}"

# import apis into sdk package
{{#apiInfo}}{{#apis}}from {{apiPackage}}.{{classVarName}} import {{classname}}
{{/apis}}{{/apiInfo}}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
```python
from __future__ import print_function
import time
import {{{packageName}}}
from {{{packageName}}}.rest import ApiException
from pprint import pprint
{{#apiInfo}}{{#apis}}{{#-first}}{{#operations}}{{#operation}}{{#-first}}{{#hasAuthMethods}}{{#authMethods}}{{#isBasic}}
# Configure HTTP basic authorization: {{{name}}}
configuration = {{{packageName}}}.Configuration()
configuration.username = 'YOUR_USERNAME'
configuration.password = 'YOUR_PASSWORD'{{/isBasic}}{{#isApiKey}}
# Configure API key authorization: {{{name}}}
configuration = {{{packageName}}}.Configuration()
configuration.api_key['{{{keyParamName}}}'] = 'YOUR_API_KEY'
# Uncomment below to setup prefix (e.g. Bearer) for API key, if needed
# configuration.api_key_prefix['{{{keyParamName}}}'] = 'Bearer'{{/isApiKey}}{{#isOAuth}}
# Configure OAuth2 access token for authorization: {{{name}}}
configuration = {{{packageName}}}.Configuration()
configuration.access_token = 'YOUR_ACCESS_TOKEN'{{/isOAuth}}{{/authMethods}}
{{/hasAuthMethods}}

# create an instance of the API class
api_instance = {{{packageName}}}.{{{classname}}}({{{packageName}}}.ApiClient(configuration))
{{#allParams}}{{paramName}} = {{{example}}} # {{{dataType}}} | {{{description}}}{{^required}} (optional){{/required}}{{#defaultValue}} (default to {{{.}}}){{/defaultValue}}
{{/allParams}}

try:
{{#summary}} # {{{.}}}
{{/summary}} {{#returnType}}api_response = {{/returnType}}api_instance.{{{operationId}}}({{#allParams}}{{#required}}{{paramName}}{{/required}}{{^required}}{{paramName}}={{paramName}}{{/required}}{{#hasMore}}, {{/hasMore}}{{/allParams}}){{#returnType}}
pprint(api_response){{/returnType}}
except ApiException as e:
print("Exception when calling {{classname}}->{{operationId}}: %s\n" % e)
{{/-first}}{{/operation}}{{/operations}}{{/-first}}{{/apis}}{{/apiInfo}}
```

## Documentation for API Endpoints

All URIs are relative to *{{basePath}}*

Class | Method | HTTP request | Description
------------ | ------------- | ------------- | -------------
{{#apiInfo}}{{#apis}}{{#operations}}{{#operation}}*{{classname}}* | [**{{operationId}}**]({{apiDocPath}}{{classname}}.md#{{operationIdLowerCase}}) | **{{httpMethod}}** {{path}} | {{#summary}}{{summary}}{{/summary}}
{{/operation}}{{/operations}}{{/apis}}{{/apiInfo}}

## Documentation For Models

{{#models}}{{#model}} - [{{{classname}}}]({{modelDocPath}}{{{classname}}}.md)
{{/model}}{{/models}}

## Documentation For Authorization

{{^authMethods}} All endpoints do not require authorization.
{{/authMethods}}{{#authMethods}}{{#last}} Authentication schemes defined for the API:{{/last}}{{/authMethods}}
{{#authMethods}}## {{{name}}}

{{#isApiKey}}- **Type**: API key
- **API key parameter name**: {{{keyParamName}}}
- **Location**: {{#isKeyInQuery}}URL query string{{/isKeyInQuery}}{{#isKeyInHeader}}HTTP header{{/isKeyInHeader}}
{{/isApiKey}}
{{#isBasic}}- **Type**: HTTP basic authentication
{{/isBasic}}
{{#isOAuth}}- **Type**: OAuth
- **Flow**: {{{flow}}}
- **Authorization URL**: {{{authorizationUrl}}}
- **Scopes**: {{^scopes}}N/A{{/scopes}}
{{#scopes}} - **{{{scope}}}**: {{{description}}}
{{/scopes}}
{{/isOAuth}}

{{/authMethods}}

## Author

{{#apiInfo}}{{#apis}}{{^hasMore}}{{infoEmail}}
{{/hasMore}}{{/apis}}{{/apiInfo}}
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ public Map<String, String> createOptions() {
.put(CodegenConstants.PACKAGE_VERSION, PACKAGE_VERSION_VALUE)
.put(CodegenConstants.SORT_PARAMS_BY_REQUIRED_FLAG, "true")
.put(CodegenConstants.HIDE_GENERATION_TIMESTAMP, "true")
.put(CodegenConstants.SOURCECODEONLY_GENERATION, "false")
.put(CodegenConstants.LIBRARY, "urllib3")
.build();
}
Expand Down
1 change: 1 addition & 0 deletions samples/client/petstore/python-asyncio/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -179,3 +179,4 @@ Class | Method | HTTP request | Description




8 changes: 4 additions & 4 deletions samples/client/petstore/python-asyncio/docs/PetApi.md
Original file line number Diff line number Diff line change
Expand Up @@ -430,7 +430,7 @@ Name | Type | Description | Notes
[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)

# **upload_file_with_required_file**
> ApiResponse upload_file_with_required_file(pet_id, file, additional_metadata=additional_metadata)
> ApiResponse upload_file_with_required_file(pet_id, required_file, additional_metadata=additional_metadata)
uploads an image (required)

Expand All @@ -449,12 +449,12 @@ configuration.access_token = 'YOUR_ACCESS_TOKEN'
# create an instance of the API class
api_instance = petstore_api.PetApi(petstore_api.ApiClient(configuration))
pet_id = 56 # int | ID of pet to update
file = '/path/to/file' # file | file to upload
required_file = '/path/to/file' # file | file to upload
additional_metadata = 'additional_metadata_example' # str | Additional data to pass to server (optional)

try:
# uploads an image (required)
api_response = api_instance.upload_file_with_required_file(pet_id, file, additional_metadata=additional_metadata)
api_response = api_instance.upload_file_with_required_file(pet_id, required_file, additional_metadata=additional_metadata)
pprint(api_response)
except ApiException as e:
print("Exception when calling PetApi->upload_file_with_required_file: %s\n" % e)
Expand All @@ -465,7 +465,7 @@ except ApiException as e:
Name | Type | Description | Notes
------------- | ------------- | ------------- | -------------
**pet_id** | **int**| ID of pet to update |
**file** | **file**| file to upload |
**required_file** | **file**| file to upload |
**additional_metadata** | **str**| Additional data to pass to server | [optional]

### Return type
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@

from __future__ import absolute_import

__version__ = "1.0.0"

# import apis into sdk package
from petstore_api.api.another_fake_api import AnotherFakeApi
from petstore_api.api.fake_api import FakeApi
Expand Down
Loading

0 comments on commit 9a136ef

Please sign in to comment.