diff --git a/.gitignore b/.gitignore
index c904ba4a5fe5..d55a8014a342 100644
--- a/.gitignore
+++ b/.gitignore
@@ -55,3 +55,9 @@ samples/client/petstore/python/.projectile
samples/client/petstore/python/.venv/
*/.settings
+
+*.mustache~
+*.java~
+*.pm~
+*.xml~
+*.t~
\ No newline at end of file
diff --git a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/PerlClientCodegen.java b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/PerlClientCodegen.java
index ddbd6c7e2170..27f39f11ed0d 100644
--- a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/PerlClientCodegen.java
+++ b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/PerlClientCodegen.java
@@ -99,6 +99,9 @@ public class PerlClientCodegen extends DefaultCodegen implements CodegenConfig {
supportingFiles.add(new SupportingFile("Configuration.mustache", ("lib/WWW/" + moduleName).replace('/', File.separatorChar), "Configuration.pm"));
supportingFiles.add(new SupportingFile("BaseObject.mustache", ("lib/WWW/" + moduleName).replace('/', File.separatorChar), "Object/BaseObject.pm"));
supportingFiles.add(new SupportingFile("ApiFactory.mustache", ("lib/WWW/" + moduleName).replace('/', File.separatorChar), "ApiFactory.pm"));
+ supportingFiles.add(new SupportingFile("Role.mustache", ("lib/WWW/" + moduleName).replace('/', File.separatorChar), "Role.pm"));
+ supportingFiles.add(new SupportingFile("AutoDoc.mustache", ("lib/WWW/" + moduleName + "/Role").replace('/', File.separatorChar), "AutoDoc.pm"));
+ supportingFiles.add(new SupportingFile("autodoc.script.mustache", ("bin/").replace('/', File.separatorChar), "autodoc"));
}
public CodegenType getTag() {
diff --git a/modules/swagger-codegen/src/main/resources/perl/ApiClient.mustache b/modules/swagger-codegen/src/main/resources/perl/ApiClient.mustache
index 0cdb40325c54..bf1220912d20 100644
--- a/modules/swagger-codegen/src/main/resources/perl/ApiClient.mustache
+++ b/modules/swagger-codegen/src/main/resources/perl/ApiClient.mustache
@@ -20,7 +20,9 @@ use Module::Runtime qw(use_module);
use WWW::{{moduleName}}::Configuration;
-sub new
+use base 'Class::Singleton';
+
+sub _new_instance
{
my $class = shift;
my (%args) = (
@@ -32,6 +34,8 @@ sub new
return bless \%args, $class;
}
+sub _cfg {'WWW::{{moduleName}}::Configuration'}
+
# Set the user agent of the API client
#
# @param string $user_agent The user agent of the API client
@@ -288,13 +292,15 @@ sub select_header_content_type
# @return string API key with the prefix
sub get_api_key_with_prefix
{
- my ($self, $api_key) = @_;
- if ($WWW::{{moduleName}}::Configuration::api_key_prefix->{$api_key}) {
- return $WWW::{{moduleName}}::Configuration::api_key_prefix->{$api_key}." ".$WWW::{{moduleName}}::Configuration::api_key->{$api_key};
- } else {
- return $WWW::{{moduleName}}::Configuration::api_key->{$api_key};
- }
-}
+ my ($self, $key_name) = @_;
+
+ my $api_key = $WWW::{{moduleName}}::Configuration::api_key->{$key_name};
+
+ return unless $api_key;
+
+ my $prefix = $WWW::{{moduleName}}::Configuration::api_key_prefix->{$key_name};
+ return $prefix ? "$prefix $api_key" : $api_key;
+}
# update header and query param based on authentication setting
#
@@ -304,17 +310,8 @@ sub get_api_key_with_prefix
sub update_params_for_auth {
my ($self, $header_params, $query_params, $auth_settings) = @_;
- # we can defer to the application
- if ($self->{auth_setup_handler} && ref($self->{auth_setup_handler}) eq 'CODE') {
- $self->{auth_setup_handler}->( api_client => $self,
- header_params => $header_params,
- query_params => $query_params,
- auth_settings => $auth_settings, # presumably this won't be defined if we're doing it this way
- );
- return;
- }
-
- return if (!defined($auth_settings) || scalar(@$auth_settings) == 0);
+ return $self->_global_auth_setup($header_params, $query_params)
+ unless $auth_settings && @$auth_settings;
# one endpoint can have more than 1 auth settings
foreach my $auth (@$auth_settings) {
@@ -327,10 +324,47 @@ sub update_params_for_auth {
}
{{/authMethods}}
else {
- # TODO show warning about security definition not found
+ # TODO show warning about security definition not found
}
}
}
+# The endpoint API class has not found any settings for auth. This may be deliberate,
+# in which case update_params_for_auth() will be a no-op. But it may also be that the
+# swagger spec does not describe the intended authorization. So we check in the config for any
+# auth tokens and if we find any, we use them for all endpoints;
+sub _global_auth_setup {
+ my ($self, $header_params, $query_params) = @_;
+
+ my $tokens = $self->_cfg->get_tokens;
+ return unless keys %$tokens;
+
+ # basic
+ if (my $uname = delete $tokens->{username}) {
+ my $pword = delete $tokens->{password};
+ $header_params->{'Authorization'} = 'Basic '.encode_base64($uname.":".$pword);
+ }
+
+ # oauth
+ if (my $access_token = delete $tokens->{access_token}) {
+ $header_params->{'Authorization'} = 'Bearer ' . $access_token;
+ }
+
+ # other keys
+ foreach my $token_name (keys %$tokens) {
+ my $in = $tokens->{$token_name}->{in};
+ my $token = $self->get_api_key_with_prefix($token_name);
+ if ($in eq 'head') {
+ $header_params->{$token_name} = $token;
+ }
+ elsif ($in eq 'query') {
+ $query_params->{$token_name} = $token;
+ }
+ else {
+ die "Don't know where to put token '$token_name' ('$in' is not 'head' or 'query')";
+ }
+ }
+}
+
1;
diff --git a/modules/swagger-codegen/src/main/resources/perl/ApiFactory.mustache b/modules/swagger-codegen/src/main/resources/perl/ApiFactory.mustache
index fc309c91b9cf..fc119f7a9026 100644
--- a/modules/swagger-codegen/src/main/resources/perl/ApiFactory.mustache
+++ b/modules/swagger-codegen/src/main/resources/perl/ApiFactory.mustache
@@ -21,9 +21,7 @@ use WWW::{{moduleName}}::ApiClient;
use WWW::{{moduleName}}::ApiFactory;
- my $api_factory = WWW::{{moduleName}}::ApiFactory->new( base_url => 'http://petstore.swagger.io/v2',
- ..., # other args for ApiClient constructor
- );
+ my $api_factory = WWW::{{moduleName}}::ApiFactory->new( ... ); # any args for ApiClient constructor
# later...
my $pet_api = $api_factory->get_api('Pet');
@@ -47,26 +45,16 @@ my %_apis = map { $_ =~ /^WWW::{{moduleName}}::(.*)$/; $1 => $_ }
=head1 new()
- All parameters are optional, and are passed to and stored on the api_client object.
+ Any parameters are optional, and are passed to and stored on the api_client object.
- base_url: supply this to change the default base URL taken from the Swagger definition.
+ base_url: (optional)
+ supply this to change the default base URL taken from the Swagger definition.
- auth_setup_handler: a coderef you can supply to set up authentication.
-
- The coderef receives a hashref with keys: api_client, query_params, header_params, auth_settings.
-
- my $api_factory = WWW::{{moduleName}}::ApiFactory->new( auth_setup_handler => \&setup_auth ); );
-
- sub setup_auth {
- my %p = @_;
- $p{header_params}->{'X-SomeApp-FunkyKeyName'} = 'aaaaabbbbbcccccddddd';
- }
-
=cut
sub new {
my ($class, %p) = (shift, @_);
- $p{api_client} = WWW::{{moduleName}}::ApiClient->new(%p);
+ $p{api_client} = WWW::{{moduleName}}::ApiClient->instance(%p);
return bless \%p, $class;
}
@@ -95,4 +83,18 @@ sub get_api {
sub api_client { $_[0]->{api_client} }
+=head1 apis_available()
+=cut
+
+sub apis_available { return map { $_ =~ s/Api$//; $_ } sort keys %_apis }
+
+=head1 classname_for()
+=cut
+
+sub classname_for {
+ my ($self, $api_name) = @_;
+ return $_apis{"${api_name}Api"};
+}
+
+
1;
diff --git a/modules/swagger-codegen/src/main/resources/perl/AutoDoc.mustache b/modules/swagger-codegen/src/main/resources/perl/AutoDoc.mustache
new file mode 100644
index 000000000000..76da048b0693
--- /dev/null
+++ b/modules/swagger-codegen/src/main/resources/perl/AutoDoc.mustache
@@ -0,0 +1,427 @@
+package WWW::{{moduleName}}::Role::AutoDoc;
+use List::MoreUtils qw(uniq);
+
+use Moose::Role;
+
+sub autodoc {
+ my ($self, $how) = @_;
+
+ die "Unknown format '$how'" unless $how =~ /^(pod|wide|narrow)$/;
+
+ $self->_printisa($how);
+ $self->_printmethods($how);
+ $self->_printattrs($how);
+ print "\n";
+}
+
+sub _printisa {
+ my ($self, $how) = @_;
+ my $meta = $self->meta;
+
+ my $myclass = ref $self;
+
+ my $super = join ', ', $meta->superclasses;
+ my @roles = $meta->calculate_all_roles;
+ #shift(@roles) if @roles > 1; # if > 1, the first is a composite, the rest are the roles
+
+ my $isa = join ', ', grep {$_ ne $myclass} $meta->linearized_isa;
+ my $sub = join ', ', $meta->subclasses;
+ my $dsub = join ', ', $meta->direct_subclasses;
+
+ my $app_name = $self->version_info->{app_name};
+ my $app_version = $self->version_info->{app_version};
+ my $generated_date = $self->version_info->{generated_date};
+ my $generator_class = $self->version_info->{generator_class};
+
+ $~ = $how eq 'pod' ? 'INHERIT_POD' : 'INHERIT';
+ write;
+
+ my ($rolepkg, $role_reqs);
+
+ foreach my $role (@roles) {
+ $rolepkg = $role->{package} || next; # some are anonymous, or something
+ next if $rolepkg eq 'WWW::{{moduleName}}::Role::AutoDoc';
+ $role_reqs = join ', ', keys %{$role->{required_methods}};
+ $role_reqs ||= '';
+ $~ = $how eq 'pod' ? 'ROLES_POD' : 'ROLES';
+ write;
+ }
+
+ if ($how eq 'pod') {
+ $~ = 'ROLES_POD_CLOSE';
+ write;
+ }
+
+# ----- format specs -----
+ format INHERIT =
+
+@* -
+$myclass
+ ISA: @*
+ $isa
+ Direct subclasses: @*
+ $dsub
+ All subclasses: @*
+ $sub
+
+ Target API: @* @*
+ $app_name, $app_version
+ Generated on: @*
+ $generated_date
+ Generator class: @*
+ $generator_class
+
+.
+ format ROLES =
+ Composes: ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< ~
+ $rolepkg
+ requires: ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< ~
+ $role_reqs
+ ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< ~~
+ $role_reqs
+.
+
+ format INHERIT_POD =
+=head1 NAME
+
+@*
+$myclass
+
+=head1 VERSION
+
+=head2 @* version: @*
+ $app_name, $app_version
+
+Automatically generated by the Perl Swagger Codegen project:
+
+=over 4
+
+=item Build date: @*
+ $generated_date
+
+=item Build package: @*
+ $generator_class
+
+=item Codegen version:
+
+
+=back
+
+=head1 INHERITANCE
+
+=head2 Base class(es)
+
+@*
+$isa
+
+=head2 Direct subclasses
+
+@*
+$dsub
+
+=head2 All subclasses
+
+@*
+$sub
+
+
+=head1 COMPOSITION
+
+@* composes the following roles:
+$myclass
+
+
+.
+ format ROLES_POD =
+=head2 C<@*>
+ $rolepkg
+
+Requires:
+
+@*
+$role_reqs
+
+.
+ format ROLES_POD_CLOSE =
+
+
+.
+# ----- / format specs -----
+}
+
+sub _printmethods {
+ my ($self, $how) = @_;
+
+ if ($how eq 'narrow') {
+ print <
_printmethod($_, $how) for uniq sort $self->meta->get_all_method_names; #$self->meta->get_method_list,
+
+ if ($how eq 'pod') {
+ $~ = 'METHOD_POD_CLOSE';
+ write;
+ }
+
+
+}
+
+sub _printmethod {
+ my ($self, $methodname, $how) = @_;
+ return if $methodname =~ /^_/;
+ return if $self->meta->has_attribute($methodname);
+ my %internal = map {$_ => 1} qw(BUILD BUILDARGS meta can new DEMOLISHALL DESTROY
+ DOES isa BUILDALL does VERSION dump
+ );
+ return if $internal{$methodname};
+ my $method = $self->meta->get_method($methodname) or return; # symbols imported into namespaces i.e. not known by Moose
+
+ return if $method->original_package_name eq __PACKAGE__;
+
+ my $delegate_to = '';
+ my $via = '';
+ my $on = '';
+ my $doc = '';
+ my $original_pkg = $method->original_package_name;
+ if ($method->can('associated_attribute')) {
+ $delegate_to = $method->delegate_to_method;
+ my $aa = $method->associated_attribute;
+ $on = $aa->{isa};
+ $via = $aa->{name};
+ $original_pkg = $on;
+ $doc = $original_pkg->method_documentation->{$delegate_to}->{summary};
+ }
+ else {
+ $doc = $method->documentation;
+ }
+
+ if ($how eq 'narrow') {
+ $~ = 'METHOD_NARROW';
+ write;
+ }
+ elsif ($how eq 'pod' and $delegate_to) {
+ $~ = 'METHOD_POD_DELEGATED';
+ write;
+ }
+ elsif ($how eq 'pod') {
+ $~ = 'METHOD_POD';
+ write;
+ }
+ else {
+ $~ = 'METHOD';
+ write;
+ }
+
+# ----- format specs -----
+ format METHODHEAD =
+
+METHODS
+-------
+Name delegates to on via
+===========================================================================================================================================================================
+.
+ format METHOD =
+@<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< @<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<... @<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<... @<<<<<<<<<<<<<<<<...
+$methodname, $delegate_to, $on, $via
+.
+
+ format METHOD_NARROW =
+@*
+$methodname
+ original pkg: @*
+ $original_pkg
+ delegates to: @*
+ $delegate_to
+ on: @*
+ $on
+ via: @*
+ $via
+
+.
+
+ format METHODHEAD_POD =
+
+=head1 METHODS
+
+.
+
+ format METHOD_POD =
+
+=head2 C<@*()>
+ $methodname
+
+ Defined in: @*
+ $original_pkg
+
+
+.
+ format METHOD_POD_DELEGATED =
+
+=head2 C<@*()>
+ $methodname
+
+ Defined in: @*
+ $original_pkg
+ Delegates to: @*()
+ $delegate_to
+ On: @*
+ $on
+ Via: @*()
+ $via
+ Doc: @*
+ $doc
+ Same as: $self->@*->@*()
+ $via, $delegate_to
+
+.
+ format METHOD_POD_CLOSE =
+
+.
+# ----- / format specs -----
+}
+
+sub _printattrs {
+ my ($self, $how) = @_;
+
+ if ($how eq 'narrow') {
+ print <_printattr($_, $how) for sort $self->meta->get_attribute_list;
+
+ if ($how eq 'pod') {
+ $~ = 'ATTR_POD_CLOSE';
+ write;
+ }
+}
+
+sub _printattr {
+ my ($self, $attrname, $how) = @_;
+ return if $attrname =~ /^_/;
+ my $attr = $self->meta->get_attribute($attrname) or die "No attr for $attrname";
+
+ my $is;
+ $is = 'rw' if $attr->get_read_method && $attr->get_write_method;
+ $is = 'ro' if $attr->get_read_method && ! $attr->get_write_method;
+ $is = 'wo' if $attr->get_write_method && ! $attr->get_read_method;
+ $is = '--' if ! $attr->get_write_method && ! $attr->get_read_method;
+ $is or die "No \$is for $attrname";
+
+ my $tc = $attr->type_constraint || '';
+ my $from = $attr->associated_class->name || '';
+ my $reqd = $attr->is_required ? 'yes' : 'no';
+ my $lazy = $attr->is_lazy ? 'yes' : 'no';
+ my $has_doc = $attr->has_documentation ? 'yes' : 'no'; # *_api attributes will never have doc, but other attributes might have
+ my $doc = $attr->documentation || '';
+ my $handles = join ', ', sort @{$attr->handles || []};
+ $handles ||= '';
+
+ if ($how eq 'narrow') {
+ $~ = 'ATTR_NARROW';
+ }
+ elsif ($how eq 'pod') {
+ $~ = 'ATTR_POD';
+ }
+ else {
+ $~ = 'ATTR';
+ }
+
+ write;
+
+# ----- format specs -----
+ format ATTRHEAD =
+
+ATTRIBUTES
+----------
+Name is isa reqd lazy doc handles
+==============================================================================================================
+.
+ format ATTR =
+@<<<<<<<<<<<<<<<<< @< @<<<<<<<<<<<<<<<<<<<<<<<< @<<< @<<< @<< ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
+$attrname, $is, $tc, $reqd, $lazy, $has_doc, $handles
+ ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< ~~
+ $handles
+.
+
+ format ATTR_NARROW =
+@*
+$attrname
+ is: @*
+ $is
+ isa: @*
+ $tc
+ reqd: @*
+ $reqd
+ lazy: @*
+ $lazy
+ doc: @*
+ $doc
+ handles: ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
+ $handles
+ ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< ~~
+ $handles
+
+.
+ format ATTRHEAD_POD =
+=head1 ATTRIBUTES
+
+.
+ format ATTR_POD =
+
+=head2 C<@*>
+ $attrname
+
+ is: @*
+ $is
+ isa: @*
+ $tc
+ reqd: @*
+ $reqd
+ lazy: @*
+ $lazy
+ doc: @*
+ $doc
+ handles: ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
+ $handles
+ ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< ~~
+ $handles
+
+.
+ format ATTR_POD_CLOSE =
+
+
+.
+# ----- / format specs -----
+}
+
+
+
+1;
\ No newline at end of file
diff --git a/modules/swagger-codegen/src/main/resources/perl/BaseObject.mustache b/modules/swagger-codegen/src/main/resources/perl/BaseObject.mustache
index f2a58efdb68f..a41931940bae 100644
--- a/modules/swagger-codegen/src/main/resources/perl/BaseObject.mustache
+++ b/modules/swagger-codegen/src/main/resources/perl/BaseObject.mustache
@@ -20,8 +20,10 @@ use base ("Class::Accessor", "Class::Data::Inheritable");
#NOTE: This class is auto generated by the swagger code generator program. Do not edit the class manually.
#
-__PACKAGE__->mk_classdata('attribute_map');
-__PACKAGE__->mk_classdata('swagger_types');
+__PACKAGE__->mk_classdata('attribute_map' => {});
+__PACKAGE__->mk_classdata('swagger_types' => {});
+__PACKAGE__->mk_classdata('method_documentation' => {});
+__PACKAGE__->mk_classdata('class_documentation' => {});
# new object
sub new {
diff --git a/modules/swagger-codegen/src/main/resources/perl/Configuration.mustache b/modules/swagger-codegen/src/main/resources/perl/Configuration.mustache
index d0b8b2c0e684..75a1ba7f61a6 100644
--- a/modules/swagger-codegen/src/main/resources/perl/Configuration.mustache
+++ b/modules/swagger-codegen/src/main/resources/perl/Configuration.mustache
@@ -10,13 +10,13 @@ use Carp;
use constant VERSION => '{{moduleVersion}}';
# class/static variables
-our $api_client;
our $http_timeout = 180;
our $http_user_agent = 'Perl-Swagger';
# authenticaiton setting
our $api_key = {};
our $api_key_prefix = {};
+our $api_key_in = {};
# username and password for HTTP basic authentication
our $username = '';
@@ -25,4 +25,56 @@ our $password = '';
# access token for OAuth
our $access_token = '';
+sub get_tokens {
+ my $class = shift;
+
+ my $tokens = {};
+ $tokens->{username} = $username if $username;
+ $tokens->{password} = $password if $password;
+ $tokens->{access_token} = $access_token if $access_token;
+
+ foreach my $token_name (keys %{ $api_key }) {
+ $tokens->{$token_name}->{token} = $api_key->{$token_name};
+ $tokens->{$token_name}->{prefix} = $api_key_prefix->{$token_name};
+ $tokens->{$token_name}->{in} = $api_key_in->{$token_name};
+ }
+
+ return $tokens;
+}
+
+sub clear_tokens {
+ my $class = shift;
+ my %tokens = %{$class->get_tokens}; # copy
+
+ $username = undef;
+ $password = undef;
+ $access_token = undef;
+
+ $api_key = {};
+ $api_key_prefix = {};
+ $api_key_in = {};
+
+ return \%tokens;
+}
+
+sub accept_tokens {
+ my ($class, $tokens) = @_;
+
+ foreach my $known_name (qw(username password access_token)) {
+ next unless $tokens->{$known_name};
+ eval "\$$known_name = delete \$tokens->{\$known_name}";
+ die $@ if $@;
+ }
+
+ foreach my $token_name (keys %$tokens) {
+ $api_key->{$token_name} = $tokens->{$token_name}->{token};
+ if ($tokens->{$token_name}->{prefix}) {
+ $api_key_prefix->{$token_name} = $tokens->{$token_name}->{prefix};
+ }
+ my $in = $tokens->{$token_name}->{in} || 'head';
+ croak "Tokens can only go in 'head' or 'query' (not in '$in')" unless $in =~ /^(?:head|query)$/;
+ $api_key_in->{$token_name} = $in;
+ }
+}
+
1;
diff --git a/modules/swagger-codegen/src/main/resources/perl/README.md b/modules/swagger-codegen/src/main/resources/perl/README.md
new file mode 100644
index 000000000000..8d0b7695c153
--- /dev/null
+++ b/modules/swagger-codegen/src/main/resources/perl/README.md
@@ -0,0 +1,219 @@
+# NAME
+
+WWW::{{moduleName}}::Role - a Moose role for the {{appName}}
+
+## {{appName}} version: {{appVersion}}
+
+# VERSION
+
+Automatically generated by the Perl Swagger Codegen project:
+
+- Build date: {{generatedDate}}
+- Build package: {{generatorClass}}
+- Codegen version:
+
+## A note on Moose
+
+This role is the only component of the library that uses Moose. See
+WWW::{{moduleName}}::ApiFactory for non-Moosey usage.
+
+# SYNOPSIS
+
+The Perl Swagger Codegen project builds a library of Perl modules to interact with
+a web service defined by a Swagger specification. See below for how to build the
+library.
+
+This module provides an interface to the generated library. All the classes,
+objects, and methods (well, not quite \*all\*, see below) are flattened into this
+role.
+
+ package MyApp;
+ use Moose;
+ with 'WWW::{{moduleName}}::Role';
+
+ package main;
+
+ my $api = MyApp->new({ tokens => $tokens });
+
+ my $pet = $api->get_pet_by_id(pet_id => $pet_id);
+
+
+## Structure of the library
+
+The library consists of a set of API classes, one for each endpoint. These APIs
+implement the method calls available on each endpoint.
+
+Additionally, there is a set of "object" classes, which represent the objects
+returned by and sent to the methods on the endpoints.
+
+An API factory class is provided, which builds instances of each endpoint API.
+
+This Moose role flattens all the methods from the endpoint APIs onto the consuming
+class. It also provides methods to retrieve the endpoint API objects, and the API
+factory object, should you need it.
+
+For documentation of all these methods, see AUTOMATIC DOCUMENTATION below.
+
+## Configuring authentication
+
+In the normal case, the Swagger spec will describe what parameters are
+required and where to put them. You just need to supply the tokens.
+
+ my $tokens = {
+ # basic
+ username => $username,
+ password => $password,
+
+ # oauth
+ access_token => $oauth_token,
+
+ # keys
+ $some_key => { token => $token,
+ prefix => $prefix,
+ in => $in, # 'head||query',
+ },
+
+ $another => { token => $token,
+ prefix => $prefix,
+ in => $in, # 'head||query',
+ },
+ ...,
+
+ };
+
+ my $api = MyApp->new({ tokens => $tokens });
+
+Note these are all optional, as are `prefix` and `in`, and depend on the API
+you are accessing. Usually `prefix` and `in` will be determined by the code generator from
+the spec and you will not need to set them at run time. If not, `in` will
+default to 'head' and `prefix` to the empty string.
+
+The tokens will be placed in the `WWW::{{moduleName}}::Configuration` namespace
+as follows, but you don't need to know about this.
+
+- `$WWW::{{moduleName}}::Configuration::username`
+
+ String. The username for basic auth.
+
+- `$WWW::{{moduleName}}::Configuration::password`
+
+ String. The password for basic auth.
+
+- `$WWW::{{moduleName}}::Configuration::api_key`
+
+ Hashref. Keyed on the name of each key (there can be multiple tokens).
+
+ $WWW::{{moduleName}}::Configuration::api_key = {
+ secretKey => 'aaaabbbbccccdddd',
+ anotherKey => '1111222233334444',
+ };
+
+- `$WWW::{{moduleName}}::Configuration::api_key_prefix`
+
+ Hashref. Keyed on the name of each key (there can be multiple tokens). Note not
+ all api keys require a prefix.
+
+ $WWW::{{moduleName}}::Configuration::api_key_prefix = {
+ secretKey => 'string',
+ anotherKey => 'same or some other string',
+ };
+
+- `$WWW::{{moduleName}}::Configuration::access_token`
+
+ String. The OAuth access token.
+
+# METHODS
+
+## `base_url`
+
+The generated code has the `base_url` already set as a default value. This method
+returns (and optionally sets, but only if the API client has not been
+created yet) the current value of `base_url`.
+
+## `api_factory`
+
+Returns an API factory object. You probably won't need to call this directly.
+
+ $self->api_factory('Pet'); # returns a WWW::{{moduleName}}::PetApi instance
+
+ $self->pet_api; # the same
+
+# MISSING METHODS
+
+Most of the methods on the API are delegated to individual endpoint API objects
+(e.g. Pet API, Store API, User API etc). Where different endpoint APIs use the
+same method name (e.g. `new()`), these methods can't be delegated. So you need
+to call `$api->pet_api->new()`.
+
+In principle, every API is susceptible to the presence of a few, random, undelegatable
+method names. In practice, because of the way method names are constructed, it's
+unlikely in general that any methods will be undelegatable, except for:
+
+ new()
+ class_documentation()
+ method_documentation()
+
+To call these methods, you need to get a handle on the relevant object, either
+by calling `$api->foo_api` or by retrieving an object, e.g.
+`$api->get_pet_by_id(pet_id => $pet_id)`. They are class methods, so
+you could also call them on class names.
+
+# BUILDING YOUR LIBRARY
+
+See the homepage `https://github.com/swagger-api/swagger-codegen` for full details.
+But briefly, clone the git repository, build the codegen codebase, set up your build
+config file, then run the API build script. You will need git, Java 7 and Apache
+maven 3.0.3 or better already installed.
+
+The config file should specify the project name for the generated library:
+
+ {"moduleName":"MyProjectName"}
+
+Your library files will be built under `WWW::MyProjectName`.
+
+ $ git clone https://github.com/swagger-api/swagger-codegen.git
+ $ cd swagger-codegen
+ $ mvn package
+ $ java -jar modules/swagger-codegen-cli/target/swagger-codegen-cli.jar generate \
+ -i [URL or file path to JSON swagger API spec] \
+ -l perl \
+ -c /path/to/config/file.json \
+ -o /path/to/output/folder
+
+Bang, all done. Run the `autodoc` script in the `bin` directory to see the API
+you just built.
+
+# AUTOMATIC DOCUMENTATION
+
+You can print out a summary of the generated API by running the included
+`autodoc` script in the `bin` directory of your generated library. A few
+output formats are supported:
+
+ Usage: autodoc [OPTION]
+
+ -w wide format (default)
+ -n narrow format
+ -p POD format
+ -H HTML format
+ -m Markdown format
+ -h print this help message
+ -c your application class
+
+
+The `-c` option allows you to load and inspect your own application. A dummy
+namespace is used if you don't supply your own class.
+
+# DOCUMENTATION FROM THE SWAGGER SPEC
+
+Additional documentation for each class and method may be provided by the Swagger
+spec. If so, this is available via the `class_documentation()` and
+`method_documentation()` methods on each generated object class, and the
+`method_documentation()` method on the endpoint API classes:
+
+ my $cmdoc = $api->pet_api->method_documentation->{$method_name};
+
+ my $odoc = $api->get_pet_by_id->(pet_id => $pet_id)->class_documentation;
+ my $omdoc = $api->get_pet_by_id->(pet_id => $pet_id)->method_documentation->{method_name};
+
+
+Each of these calls returns a hashref with various useful pieces of information.
diff --git a/modules/swagger-codegen/src/main/resources/perl/Role.mustache b/modules/swagger-codegen/src/main/resources/perl/Role.mustache
new file mode 100644
index 000000000000..7bca8cca78d7
--- /dev/null
+++ b/modules/swagger-codegen/src/main/resources/perl/Role.mustache
@@ -0,0 +1,323 @@
+package WWW::{{moduleName}}::Role;
+use utf8;
+
+use Moose::Role;
+use namespace::autoclean;
+use Class::Inspector;
+use Log::Any qw($log);
+use WWW::{{moduleName}}::ApiFactory;
+
+has base_url => ( is => 'ro',
+ required => 0,
+ isa => 'Str',
+ documentation => 'Root of the server that requests are sent to',
+ );
+
+has api_factory => ( is => 'ro',
+ isa => 'WWW::{{moduleName}}::ApiFactory',
+ builder => '_build_af',
+ lazy => 1,
+ documentation => 'Builds an instance of the endpoint API class',
+ );
+
+has tokens => ( is => 'ro',
+ isa => 'HashRef',
+ required => 0,
+ default => sub { {} },
+ documentation => 'The auth tokens required by the application - basic, OAuth and/or API key(s)',
+ );
+
+has _cfg => ( is => 'ro',
+ isa => 'Str',
+ default => 'WWW::{{moduleName}}::Configuration',
+ );
+
+has version_info => ( is => 'ro',
+ isa => 'HashRef',
+ default => sub { {
+ app_name => '{{appName}}',
+ app_version => '{{appVersion}}',
+ generated_date => '{{generatedDate}}',
+ generator_class => '{{generatorClass}}',
+ } },
+ documentation => 'Information about the application version and the codegen codebase version'
+ );
+
+sub BUILD {
+ my $self = shift;
+
+ $self->_cfg->accept_tokens( $self->tokens ) if keys %{$self->tokens};
+
+ # ignore these symbols imported into API namespaces
+ my %outsiders = map {$_ => 1} qw( croak );
+
+ my %delegates;
+
+ # collect the methods callable on each API
+ foreach my $api_name ($self->api_factory->apis_available) {
+ my $api_class = $self->api_factory->classname_for($api_name);
+ my $methods = Class::Inspector->methods($api_class, 'expanded'); # not Moose, so use CI instead
+ my @local_methods = grep {! /^_/} grep {! $outsiders{$_}} map {$_->[2]} grep {$_->[1] eq $api_class} @$methods;
+ push( @{$delegates{$_}}, {api_name => $api_name, api_class => $api_class} ) for @local_methods;
+ }
+
+ # remove clashes
+ foreach my $method (keys %delegates) {
+ if ( @{$delegates{$method}} > 1 ) {
+ my ($apis) = delete $delegates{$method};
+ }
+ }
+
+ # build the flattened API
+ foreach my $api_name ($self->api_factory->apis_available) {
+ my $att_name = sprintf "%s_api", lc($api_name);
+ my $api_class = $self->api_factory->classname_for($api_name);
+ my @delegated = grep { $delegates{$_}->[0]->{api_name} eq $api_name } keys %delegates;
+ $log->debugf("Adding API: '%s' handles %s", $att_name, join ', ', @delegated);
+ $self->meta->add_attribute( $att_name => (
+ is => 'ro',
+ isa => $api_class,
+ default => sub {$self->api_factory->get_api($api_name)},
+ lazy => 1,
+ handles => \@delegated,
+ ) );
+ }
+}
+
+sub _build_af {
+ my $self = shift;
+ my %args;
+ $args{base_url} = $self->base_url if $self->base_url;
+ return WWW::{{moduleName}}::ApiFactory->new(%args);
+}
+
+=head1 NAME
+
+WWW::{{moduleName}}::Role - a Moose role for the {{appName}}
+
+=head2 {{appName}} version: {{appVersion}}
+
+=head1 VERSION
+
+Automatically generated by the Perl Swagger Codegen project:
+
+=over 4
+
+=item Build date: {{generatedDate}}
+
+=item Build package: {{generatorClass}}
+
+=item Codegen version:
+
+=back
+
+=head2 A note on Moose
+
+This role is the only component of the library that uses Moose. See
+WWW::{{moduleName}}::ApiFactory for non-Moosey usage.
+
+=head1 SYNOPSIS
+
+The Perl Swagger Codegen project builds a library of Perl modules to interact with
+a web service defined by a Swagger specification. See below for how to build the
+library.
+
+This module provides an interface to the generated library. All the classes,
+objects, and methods (well, not quite *all*, see below) are flattened into this
+role.
+
+ package MyApp;
+ use Moose;
+ with 'WWW::{{moduleName}}::Role';
+
+ package main;
+
+ my $api = MyApp->new({ tokens => $tokens });
+
+ my $pet = $api->get_pet_by_id(pet_id => $pet_id);
+
+=head2 Structure of the library
+
+The library consists of a set of API classes, one for each endpoint. These APIs
+implement the method calls available on each endpoint.
+
+Additionally, there is a set of "object" classes, which represent the objects
+returned by and sent to the methods on the endpoints.
+
+An API factory class is provided, which builds instances of each endpoint API.
+
+This Moose role flattens all the methods from the endpoint APIs onto the consuming
+class. It also provides methods to retrieve the endpoint API objects, and the API
+factory object, should you need it.
+
+For documentation of all these methods, see AUTOMATIC DOCUMENTATION below.
+
+=head2 Configuring authentication
+
+In the normal case, the Swagger spec will describe what parameters are
+required and where to put them. You just need to supply the tokens.
+
+ my $tokens = {
+ # basic
+ username => $username,
+ password => $password,
+
+ # oauth
+ access_token => $oauth_token,
+
+ # keys
+ $some_key => { token => $token,
+ prefix => $prefix,
+ in => $in, # 'head||query',
+ },
+
+ $another => { token => $token,
+ prefix => $prefix,
+ in => $in, # 'head||query',
+ },
+ ...,
+
+ };
+
+ my $api = MyApp->new({ tokens => $tokens });
+
+Note these are all optional, as are C and C, and depend on the API
+you are accessing. Usually C and C will be determined by the code generator from
+the spec and you will not need to set them at run time. If not, C will
+default to 'head' and C to the empty string.
+
+The tokens will be placed in the C namespace
+as follows, but you don't need to know about this.
+
+=over 4
+
+=item C<$WWW::{{moduleName}}::Configuration::username>
+
+String. The username for basic auth.
+
+=item C<$WWW::{{moduleName}}::Configuration::password>
+
+String. The password for basic auth.
+
+=item C<$WWW::{{moduleName}}::Configuration::api_key>
+
+Hashref. Keyed on the name of each key (there can be multiple tokens).
+
+ $WWW::{{moduleName}}::Configuration::api_key = {
+ secretKey => 'aaaabbbbccccdddd',
+ anotherKey => '1111222233334444',
+ };
+
+=item C<$WWW::{{moduleName}}::Configuration::api_key_prefix>
+
+Hashref. Keyed on the name of each key (there can be multiple tokens). Note not
+all api keys require a prefix.
+
+ $WWW::{{moduleName}}::Configuration::api_key_prefix = {
+ secretKey => 'string',
+ anotherKey => 'same or some other string',
+ };
+
+=item C<$WWW::{{moduleName}}::Configuration::access_token>
+
+String. The OAuth access token.
+
+=back
+
+=head1 METHODS
+
+=head2 C
+
+The generated code has the C already set as a default value. This method
+returns (and optionally sets, but only if the API client has not been
+created yet) the current value of C.
+
+=head2 C
+
+Returns an API factory object. You probably won't need to call this directly.
+
+ $self->api_factory('Pet'); # returns a WWW::{{moduleName}}::PetApi instance
+
+ $self->pet_api; # the same
+
+=head1 MISSING METHODS
+
+Most of the methods on the API are delegated to individual endpoint API objects
+(e.g. Pet API, Store API, User API etc). Where different endpoint APIs use the
+same method name (e.g. C), these methods can't be delegated. So you need
+to call C<$api-Epet_api-Enew()>.
+
+In principle, every API is susceptible to the presence of a few, random, undelegatable
+method names. In practice, because of the way method names are constructed, it's
+unlikely in general that any methods will be undelegatable, except for:
+
+ new()
+ class_documentation()
+ method_documentation()
+
+To call these methods, you need to get a handle on the relevant object, either
+by calling C<$api-Efoo_api> or by retrieving an object, e.g.
+C<$api-Eget_pet_by_id(pet_id =E $pet_id)>. They are class methods, so
+you could also call them on class names.
+
+=head1 BUILDING YOUR LIBRARY
+
+See the homepage C for full details.
+But briefly, clone the git repository, build the codegen codebase, set up your build
+config file, then run the API build script. You will need git, Java 7 and Apache
+maven 3.0.3 or better already installed.
+
+The config file should specify the project name for the generated library:
+
+ {"moduleName":"MyProjectName"}
+
+Your library files will be built under C.
+
+ $ git clone https://github.com/swagger-api/swagger-codegen.git
+ $ cd swagger-codegen
+ $ mvn package
+ $ java -jar modules/swagger-codegen-cli/target/swagger-codegen-cli.jar generate \
+ -i [URL or file path to JSON swagger API spec] \
+ -l perl \
+ -c /path/to/config/file.json \
+ -o /path/to/output/folder
+
+Bang, all done. Run the C script in the C directory to see the API
+you just built.
+
+=head1 AUTOMATIC DOCUMENTATION
+
+You can print out a summary of the generated API by running the included
+C script in the C directory of your generated library. A few
+output formats are supported:
+
+ Usage: autodoc [OPTION]
+
+ -w wide format (default)
+ -n narrow format
+ -p POD format
+ -H HTML format
+ -m Markdown format
+ -h print this help message
+ -c your application class
+
+The C<-c> option allows you to load and inspect your own application. A dummy
+namespace is used if you don't supply your own class.
+
+=head1 DOCUMENTATION FROM THE SWAGGER SPEC
+
+Additional documentation for each class and method may be provided by the Swagger
+spec. If so, this is available via the C and
+C methods on each generated object class, and the
+C method on the endpoint API classes:
+
+ my $cmdoc = $api->pet_api->method_documentation->{$method_name};
+
+ my $odoc = $api->get_pet_by_id->(pet_id => $pet_id)->class_documentation;
+ my $omdoc = $api->get_pet_by_id->(pet_id => $pet_id)->method_documentation->{method_name};
+
+Each of these calls returns a hashref with various useful pieces of information.
+
+=cut
+
+1;
diff --git a/modules/swagger-codegen/src/main/resources/perl/api.mustache b/modules/swagger-codegen/src/main/resources/perl/api.mustache
index d305d69b7faa..f25c63a528cc 100644
--- a/modules/swagger-codegen/src/main/resources/perl/api.mustache
+++ b/modules/swagger-codegen/src/main/resources/perl/api.mustache
@@ -30,11 +30,14 @@ use Log::Any qw($log);
use WWW::{{moduleName}}::ApiClient;
use WWW::{{moduleName}}::Configuration;
+use base "Class::Data::Inheritable";
+
+__PACKAGE__->mk_classdata('method_documentation' => {});
+
sub new {
my $class = shift;
- my $default_api_client = $WWW::{{moduleName}}::Configuration::api_client ? $WWW::{{moduleName}}::Configuration::api_client : WWW::{{moduleName}}::ApiClient->new;
my (%self) = (
- 'api_client' => $default_api_client,
+ 'api_client' => WWW::{{moduleName}}::ApiClient->instance,
@_
);
@@ -49,13 +52,31 @@ sub new {
{{#operations}}
{{#operation}}
+
#
# {{{nickname}}}
#
# {{{summary}}}
#
{{#allParams}}# @param {{dataType}} ${{paramName}} {{description}} {{#required}}(required){{/required}}{{^required}}(optional){{/required}}
-{{/allParams}}# @return {{#returnType}}{{{returnType}}}{{/returnType}}{{^returnType}}void{{/returnType}}
+{{/allParams}}
+{
+ my $params = {
+{{#allParams}}
+ '{{paramName}}' => {
+ data_type => '{{dataType}}',
+ description => '{{description}}',
+ required => {{#required}}'1'{{/required}}{{^required}}'0'{{/required}},
+ },
+{{/allParams}}
+ };
+ __PACKAGE__->method_documentation->{ {{nickname}} } = {
+ summary => '{{summary}}',
+ params => $params,
+ returns => {{#returnType}}'{{{returnType}}}'{{/returnType}}{{^returnType}}undef{{/returnType}},
+ };
+}
+# @return {{#returnType}}{{{returnType}}}{{/returnType}}{{^returnType}}void{{/returnType}}
#
sub {{nickname}} {
my ($self, %args) = @_;
@@ -112,7 +133,7 @@ sub {{nickname}} {
}{{/bodyParams}}
# authentication setting, if any
- my $auth_settings = [{{#authMethods}}'{{name}}'{{#hasMore}}, {{/hasMore}}{{/authMethods}}];
+ my $auth_settings = [qw({{#authMethods}}{{name}} {{/authMethods}})];
# make the API Call
{{#returnType}}my $response = $self->{api_client}->call_api($_resource_path, $_method,
diff --git a/modules/swagger-codegen/src/main/resources/perl/autodoc.script.mustache b/modules/swagger-codegen/src/main/resources/perl/autodoc.script.mustache
new file mode 100644
index 000000000000..240936d9b510
--- /dev/null
+++ b/modules/swagger-codegen/src/main/resources/perl/autodoc.script.mustache
@@ -0,0 +1,77 @@
+#!/usr/bin/perl
+use FindBin;
+use File::Spec;
+use lib File::Spec->catdir($FindBin::Bin, '..', 'lib');
+
+use Moose::Util qw(apply_all_roles);
+use Getopt::Std;
+
+my %options=();
+getopts("wnphmHc:", \%options);
+help if $options{h};
+
+my $my_app = $options{c} || 'My::App';
+
+if ($options{c}) {
+ eval <new;
+
+if ($options{H}) {
+ my $pod2html = "pod2html --backlink --css http://st.pimg.net/tucs/style.css?3";
+ open STDOUT, "| $pod2html" or die "Can't fork: $!";
+ $api->autodoc($opt);
+ close STDOUT or die "Can't close: $!";
+}
+elsif ($options{m}) {
+ my $pod2markdown = "pod2markdown --html-encode-chars 1";
+ open STDOUT, "| $pod2markdown" or die "Can't fork: $!";
+ $api->autodoc($opt);
+ close STDOUT or die "Can't close: $!";
+}
+else {
+ $api->autodoc($opt);
+}
+
+exit(0);
+
+# --------------------
+sub help {
+ print <class_documentation({description => '{{description}}',
+ class => '{{classname}}',
+ required => [], # TODO
+} );
+
+__PACKAGE__->method_documentation({
+ {{#vars}}'{{name}}' => {
+ datatype => '{{datatype}}',
+ base_name => '{{baseName}}',
+ description => '{{description}}',
+ format => '{{format}}',
+ read_only => '{{readOnly}}',
+ },
+ {{/vars}}
+});
+
__PACKAGE__->swagger_types( {
{{#vars}}'{{name}}' => '{{{datatype}}}'{{#hasMore}},
{{/hasMore}}{{/vars}}
diff --git a/samples/client/petstore/perl/README.md b/samples/client/petstore/perl/README.md
new file mode 100644
index 000000000000..adfe2455d658
--- /dev/null
+++ b/samples/client/petstore/perl/README.md
@@ -0,0 +1,281 @@
+# NAME
+
+My::App
+
+# VERSION
+
+## Swagger Petstore version: 1.0.0
+
+Automatically generated by the Perl Swagger Codegen project:
+
+- Build date: 2015-11-13T20:46:43.271Z
+- Build package: class io.swagger.codegen.languages.PerlClientCodegen
+- Codegen version:
+
+# INHERITANCE
+
+## Base class(es)
+
+Moose::Object
+
+## Direct subclasses
+
+## All subclasses
+
+# COMPOSITION
+
+My::App composes the following roles:
+
+## `WWW::SwaggerClient::Role`
+
+Requires:
+
+# METHODS
+
+## `add_pet()`
+
+ Defined in: WWW::SwaggerClient::PetApi
+ Delegates to: add_pet()
+ On: WWW::SwaggerClient::PetApi
+ Via: pet_api()
+ Doc: Add a new pet to the store
+ Same as: $self->pet_api->add_pet()
+
+## `create_user()`
+
+ Defined in: WWW::SwaggerClient::UserApi
+ Delegates to: create_user()
+ On: WWW::SwaggerClient::UserApi
+ Via: user_api()
+ Doc: Create user
+ Same as: $self->user_api->create_user()
+
+## `create_users_with_array_input()`
+
+ Defined in: WWW::SwaggerClient::UserApi
+ Delegates to: create_users_with_array_input()
+ On: WWW::SwaggerClient::UserApi
+ Via: user_api()
+ Doc: Creates list of users with given input array
+ Same as: $self->user_api->create_users_with_array_input()
+
+## `create_users_with_list_input()`
+
+ Defined in: WWW::SwaggerClient::UserApi
+ Delegates to: create_users_with_list_input()
+ On: WWW::SwaggerClient::UserApi
+ Via: user_api()
+ Doc: Creates list of users with given input array
+ Same as: $self->user_api->create_users_with_list_input()
+
+## `delete_order()`
+
+ Defined in: WWW::SwaggerClient::StoreApi
+ Delegates to: delete_order()
+ On: WWW::SwaggerClient::StoreApi
+ Via: store_api()
+ Doc: Delete purchase order by ID
+ Same as: $self->store_api->delete_order()
+
+## `delete_pet()`
+
+ Defined in: WWW::SwaggerClient::PetApi
+ Delegates to: delete_pet()
+ On: WWW::SwaggerClient::PetApi
+ Via: pet_api()
+ Doc: Deletes a pet
+ Same as: $self->pet_api->delete_pet()
+
+## `delete_user()`
+
+ Defined in: WWW::SwaggerClient::UserApi
+ Delegates to: delete_user()
+ On: WWW::SwaggerClient::UserApi
+ Via: user_api()
+ Doc: Delete user
+ Same as: $self->user_api->delete_user()
+
+## `find_pets_by_status()`
+
+ Defined in: WWW::SwaggerClient::PetApi
+ Delegates to: find_pets_by_status()
+ On: WWW::SwaggerClient::PetApi
+ Via: pet_api()
+ Doc: Finds Pets by status
+ Same as: $self->pet_api->find_pets_by_status()
+
+## `find_pets_by_tags()`
+
+ Defined in: WWW::SwaggerClient::PetApi
+ Delegates to: find_pets_by_tags()
+ On: WWW::SwaggerClient::PetApi
+ Via: pet_api()
+ Doc: Finds Pets by tags
+ Same as: $self->pet_api->find_pets_by_tags()
+
+## `get_inventory()`
+
+ Defined in: WWW::SwaggerClient::StoreApi
+ Delegates to: get_inventory()
+ On: WWW::SwaggerClient::StoreApi
+ Via: store_api()
+ Doc: Returns pet inventories by status
+ Same as: $self->store_api->get_inventory()
+
+## `get_order_by_id()`
+
+ Defined in: WWW::SwaggerClient::StoreApi
+ Delegates to: get_order_by_id()
+ On: WWW::SwaggerClient::StoreApi
+ Via: store_api()
+ Doc: Find purchase order by ID
+ Same as: $self->store_api->get_order_by_id()
+
+## `get_pet_by_id()`
+
+ Defined in: WWW::SwaggerClient::PetApi
+ Delegates to: get_pet_by_id()
+ On: WWW::SwaggerClient::PetApi
+ Via: pet_api()
+ Doc: Find pet by ID
+ Same as: $self->pet_api->get_pet_by_id()
+
+## `get_user_by_name()`
+
+ Defined in: WWW::SwaggerClient::UserApi
+ Delegates to: get_user_by_name()
+ On: WWW::SwaggerClient::UserApi
+ Via: user_api()
+ Doc: Get user by user name
+ Same as: $self->user_api->get_user_by_name()
+
+## `login_user()`
+
+ Defined in: WWW::SwaggerClient::UserApi
+ Delegates to: login_user()
+ On: WWW::SwaggerClient::UserApi
+ Via: user_api()
+ Doc: Logs user into the system
+ Same as: $self->user_api->login_user()
+
+## `logout_user()`
+
+ Defined in: WWW::SwaggerClient::UserApi
+ Delegates to: logout_user()
+ On: WWW::SwaggerClient::UserApi
+ Via: user_api()
+ Doc: Logs out current logged in user session
+ Same as: $self->user_api->logout_user()
+
+## `place_order()`
+
+ Defined in: WWW::SwaggerClient::StoreApi
+ Delegates to: place_order()
+ On: WWW::SwaggerClient::StoreApi
+ Via: store_api()
+ Doc: Place an order for a pet
+ Same as: $self->store_api->place_order()
+
+## `update_pet()`
+
+ Defined in: WWW::SwaggerClient::PetApi
+ Delegates to: update_pet()
+ On: WWW::SwaggerClient::PetApi
+ Via: pet_api()
+ Doc: Update an existing pet
+ Same as: $self->pet_api->update_pet()
+
+## `update_pet_with_form()`
+
+ Defined in: WWW::SwaggerClient::PetApi
+ Delegates to: update_pet_with_form()
+ On: WWW::SwaggerClient::PetApi
+ Via: pet_api()
+ Doc: Updates a pet in the store with form data
+ Same as: $self->pet_api->update_pet_with_form()
+
+## `update_user()`
+
+ Defined in: WWW::SwaggerClient::UserApi
+ Delegates to: update_user()
+ On: WWW::SwaggerClient::UserApi
+ Via: user_api()
+ Doc: Updated user
+ Same as: $self->user_api->update_user()
+
+## `upload_file()`
+
+ Defined in: WWW::SwaggerClient::PetApi
+ Delegates to: upload_file()
+ On: WWW::SwaggerClient::PetApi
+ Via: pet_api()
+ Doc: uploads an image
+ Same as: $self->pet_api->upload_file()
+
+# ATTRIBUTES
+
+## `api_factory`
+
+ is: ro
+ isa: WWW::SwaggerClient::ApiFactory
+ reqd: no
+ lazy: yes
+ doc: Builds an instance of the endpoint API class
+ handles:
+
+## `base_url`
+
+ is: ro
+ isa: Str
+ reqd: no
+ lazy: no
+ doc: Root of the server that requests are sent to
+ handles:
+
+## `pet_api`
+
+ is: ro
+ isa: WWW::SwaggerClient::PetApi
+ reqd: no
+ lazy: yes
+ doc:
+ handles: add_pet, delete_pet, find_pets_by_status, find_pets_by_tags,
+ get_pet_by_id, update_pet, update_pet_with_form, upload_file
+
+## `store_api`
+
+ is: ro
+ isa: WWW::SwaggerClient::StoreApi
+ reqd: no
+ lazy: yes
+ doc:
+ handles: delete_order, get_inventory, get_order_by_id, place_order
+
+## `tokens`
+
+ is: ro
+ isa: HashRef
+ reqd: no
+ lazy: no
+ doc: The auth tokens required by the application - basic, OAuth and/or API key(s)
+ handles:
+
+## `user_api`
+
+ is: ro
+ isa: WWW::SwaggerClient::UserApi
+ reqd: no
+ lazy: yes
+ doc:
+ handles: create_user, create_users_with_array_input,
+ create_users_with_list_input, delete_user, get_user_by_name,
+ login_user, logout_user, update_user
+
+## `version_info`
+
+ is: ro
+ isa: HashRef
+ reqd: no
+ lazy: no
+ doc: Information about the application version and the codegen codebase version
+ handles:
diff --git a/samples/client/petstore/perl/bin/autodoc b/samples/client/petstore/perl/bin/autodoc
new file mode 100644
index 000000000000..049fcf7fecf2
--- /dev/null
+++ b/samples/client/petstore/perl/bin/autodoc
@@ -0,0 +1,77 @@
+#!/usr/bin/perl
+use FindBin;
+use File::Spec;
+use lib File::Spec->catdir($FindBin::Bin, '..', 'lib');
+
+use Moose::Util qw(apply_all_roles);
+use Getopt::Std;
+
+my %options=();
+getopts("wnphmHc:", \%options);
+help if $options{h};
+
+my $my_app = $options{c} || 'My::App';
+
+if ($options{c}) {
+ eval <new;
+
+if ($options{H}) {
+ my $pod2html = "pod2html --backlink --css http://st.pimg.net/tucs/style.css?3";
+ open STDOUT, "| $pod2html" or die "Can't fork: $!";
+ $api->autodoc($opt);
+ close STDOUT or die "Can't close: $!";
+}
+elsif ($options{m}) {
+ my $pod2markdown = "pod2markdown --html-encode-chars 1";
+ open STDOUT, "| $pod2markdown" or die "Can't fork: $!";
+ $api->autodoc($opt);
+ close STDOUT or die "Can't close: $!";
+}
+else {
+ $api->autodoc($opt);
+}
+
+exit(0);
+
+# --------------------
+sub help {
+ print <{$api_key}) {
- return $WWW::SwaggerClient::Configuration::api_key_prefix->{$api_key}." ".$WWW::SwaggerClient::Configuration::api_key->{$api_key};
- } else {
- return $WWW::SwaggerClient::Configuration::api_key->{$api_key};
- }
-}
+ my ($self, $key_name) = @_;
+
+ my $api_key = $WWW::SwaggerClient::Configuration::api_key->{$key_name};
+
+ return unless $api_key;
+
+ my $prefix = $WWW::SwaggerClient::Configuration::api_key_prefix->{$key_name};
+ return $prefix ? "$prefix $api_key" : $api_key;
+}
# update header and query param based on authentication setting
#
@@ -304,17 +310,8 @@ sub get_api_key_with_prefix
sub update_params_for_auth {
my ($self, $header_params, $query_params, $auth_settings) = @_;
- # we can defer to the application
- if ($self->{auth_setup_handler} && ref($self->{auth_setup_handler}) eq 'CODE') {
- $self->{auth_setup_handler}->( api_client => $self,
- header_params => $header_params,
- query_params => $query_params,
- auth_settings => $auth_settings, # presumably this won't be defined if we're doing it this way
- );
- return;
- }
-
- return if (!defined($auth_settings) || scalar(@$auth_settings) == 0);
+ return $self->_global_auth_setup($header_params, $query_params)
+ unless $auth_settings && @$auth_settings;
# one endpoint can have more than 1 auth settings
foreach my $auth (@$auth_settings) {
@@ -331,10 +328,47 @@ sub update_params_for_auth {
}
else {
- # TODO show warning about security definition not found
+ # TODO show warning about security definition not found
}
}
}
+# The endpoint API class has not found any settings for auth. This may be deliberate,
+# in which case update_params_for_auth() will be a no-op. But it may also be that the
+# swagger spec does not describe the intended authorization. So we check in the config for any
+# auth tokens and if we find any, we use them for all endpoints;
+sub _global_auth_setup {
+ my ($self, $header_params, $query_params) = @_;
+
+ my $tokens = $self->_cfg->get_tokens;
+ return unless keys %$tokens;
+
+ # basic
+ if (my $uname = delete $tokens->{username}) {
+ my $pword = delete $tokens->{password};
+ $header_params->{'Authorization'} = 'Basic '.encode_base64($uname.":".$pword);
+ }
+
+ # oauth
+ if (my $access_token = delete $tokens->{access_token}) {
+ $header_params->{'Authorization'} = 'Bearer ' . $access_token;
+ }
+
+ # other keys
+ foreach my $token_name (keys %$tokens) {
+ my $in = $tokens->{$token_name}->{in};
+ my $token = $self->get_api_key_with_prefix($token_name);
+ if ($in eq 'head') {
+ $header_params->{$token_name} = $token;
+ }
+ elsif ($in eq 'query') {
+ $query_params->{$token_name} = $token;
+ }
+ else {
+ die "Don't know where to put token '$token_name' ('$in' is not 'head' or 'query')";
+ }
+ }
+}
+
1;
diff --git a/samples/client/petstore/perl/lib/WWW/SwaggerClient/ApiFactory.pm b/samples/client/petstore/perl/lib/WWW/SwaggerClient/ApiFactory.pm
index 701a22603c53..f0846a9b5944 100644
--- a/samples/client/petstore/perl/lib/WWW/SwaggerClient/ApiFactory.pm
+++ b/samples/client/petstore/perl/lib/WWW/SwaggerClient/ApiFactory.pm
@@ -21,9 +21,7 @@ use WWW::SwaggerClient::ApiClient;
use WWW::SwaggerClient::ApiFactory;
- my $api_factory = WWW::SwaggerClient::ApiFactory->new( base_url => 'http://petstore.swagger.io/v2',
- ..., # other args for ApiClient constructor
- );
+ my $api_factory = WWW::SwaggerClient::ApiFactory->new( ... ); # any args for ApiClient constructor
# later...
my $pet_api = $api_factory->get_api('Pet');
@@ -47,26 +45,16 @@ my %_apis = map { $_ =~ /^WWW::SwaggerClient::(.*)$/; $1 => $_ }
=head1 new()
- All parameters are optional, and are passed to and stored on the api_client object.
+ Any parameters are optional, and are passed to and stored on the api_client object.
- base_url: supply this to change the default base URL taken from the Swagger definition.
+ base_url: (optional)
+ supply this to change the default base URL taken from the Swagger definition.
- auth_setup_handler: a coderef you can supply to set up authentication.
-
- The coderef receives a hashref with keys: api_client, query_params, header_params, auth_settings.
-
- my $api_factory = WWW::SwaggerClient::ApiFactory->new( auth_setup_handler => \&setup_auth ); );
-
- sub setup_auth {
- my %p = @_;
- $p{header_params}->{'X-SomeApp-FunkyKeyName'} = 'aaaaabbbbbcccccddddd';
- }
-
=cut
sub new {
my ($class, %p) = (shift, @_);
- $p{api_client} = WWW::SwaggerClient::ApiClient->new(%p);
+ $p{api_client} = WWW::SwaggerClient::ApiClient->instance(%p);
return bless \%p, $class;
}
@@ -95,4 +83,18 @@ sub get_api {
sub api_client { $_[0]->{api_client} }
+=head1 apis_available()
+=cut
+
+sub apis_available { return map { $_ =~ s/Api$//; $_ } sort keys %_apis }
+
+=head1 classname_for()
+=cut
+
+sub classname_for {
+ my ($self, $api_name) = @_;
+ return $_apis{"${api_name}Api"};
+}
+
+
1;
diff --git a/samples/client/petstore/perl/lib/WWW/SwaggerClient/Configuration.pm b/samples/client/petstore/perl/lib/WWW/SwaggerClient/Configuration.pm
index 6a4afe254e0b..150db4cfac2e 100644
--- a/samples/client/petstore/perl/lib/WWW/SwaggerClient/Configuration.pm
+++ b/samples/client/petstore/perl/lib/WWW/SwaggerClient/Configuration.pm
@@ -10,13 +10,13 @@ use Carp;
use constant VERSION => '1.0.0';
# class/static variables
-our $api_client;
our $http_timeout = 180;
our $http_user_agent = 'Perl-Swagger';
# authenticaiton setting
our $api_key = {};
our $api_key_prefix = {};
+our $api_key_in = {};
# username and password for HTTP basic authentication
our $username = '';
@@ -25,4 +25,56 @@ our $password = '';
# access token for OAuth
our $access_token = '';
+sub get_tokens {
+ my $class = shift;
+
+ my $tokens = {};
+ $tokens->{username} = $username if $username;
+ $tokens->{password} = $password if $password;
+ $tokens->{access_token} = $access_token if $access_token;
+
+ foreach my $token_name (keys %{ $api_key }) {
+ $tokens->{$token_name}->{token} = $api_key->{$token_name};
+ $tokens->{$token_name}->{prefix} = $api_key_prefix->{$token_name};
+ $tokens->{$token_name}->{in} = $api_key_in->{$token_name};
+ }
+
+ return $tokens;
+}
+
+sub clear_tokens {
+ my $class = shift;
+ my %tokens = %{$class->get_tokens}; # copy
+
+ $username = undef;
+ $password = undef;
+ $access_token = undef;
+
+ $api_key = {};
+ $api_key_prefix = {};
+ $api_key_in = {};
+
+ return \%tokens;
+}
+
+sub accept_tokens {
+ my ($class, $tokens) = @_;
+
+ foreach my $known_name (qw(username password access_token)) {
+ next unless $tokens->{$known_name};
+ eval "\$$known_name = delete \$tokens->{\$known_name}";
+ die $@ if $@;
+ }
+
+ foreach my $token_name (keys %$tokens) {
+ $api_key->{$token_name} = $tokens->{$token_name}->{token};
+ if ($tokens->{$token_name}->{prefix}) {
+ $api_key_prefix->{$token_name} = $tokens->{$token_name}->{prefix};
+ }
+ my $in = $tokens->{$token_name}->{in} || 'head';
+ croak "Tokens can only go in 'head' or 'query' (not in '$in')" unless $in =~ /^(?:head|query)$/;
+ $api_key_in->{$token_name} = $in;
+ }
+}
+
1;
diff --git a/samples/client/petstore/perl/lib/WWW/SwaggerClient/Object/BaseObject.pm b/samples/client/petstore/perl/lib/WWW/SwaggerClient/Object/BaseObject.pm
index fee2b06fb0ee..f99b7715ae8d 100644
--- a/samples/client/petstore/perl/lib/WWW/SwaggerClient/Object/BaseObject.pm
+++ b/samples/client/petstore/perl/lib/WWW/SwaggerClient/Object/BaseObject.pm
@@ -20,8 +20,10 @@ use base ("Class::Accessor", "Class::Data::Inheritable");
#NOTE: This class is auto generated by the swagger code generator program. Do not edit the class manually.
#
-__PACKAGE__->mk_classdata('attribute_map');
-__PACKAGE__->mk_classdata('swagger_types');
+__PACKAGE__->mk_classdata('attribute_map' => {});
+__PACKAGE__->mk_classdata('swagger_types' => {});
+__PACKAGE__->mk_classdata('method_documentation' => {});
+__PACKAGE__->mk_classdata('class_documentation' => {});
# new object
sub new {
diff --git a/samples/client/petstore/perl/lib/WWW/SwaggerClient/Object/Category.pm b/samples/client/petstore/perl/lib/WWW/SwaggerClient/Object/Category.pm
index 1e0629250377..43c12b040c73 100644
--- a/samples/client/petstore/perl/lib/WWW/SwaggerClient/Object/Category.pm
+++ b/samples/client/petstore/perl/lib/WWW/SwaggerClient/Object/Category.pm
@@ -19,6 +19,29 @@ use base "WWW::SwaggerClient::Object::BaseObject";
#NOTE: This class is auto generated by the swagger code generator program. Do not edit the class manually.
#
+__PACKAGE__->class_documentation({description => '',
+ class => 'Category',
+ required => [], # TODO
+} );
+
+__PACKAGE__->method_documentation({
+ 'id' => {
+ datatype => 'int',
+ base_name => 'id',
+ description => '',
+ format => '',
+ read_only => '',
+ },
+ 'name' => {
+ datatype => 'string',
+ base_name => 'name',
+ description => '',
+ format => '',
+ read_only => '',
+ },
+
+});
+
__PACKAGE__->swagger_types( {
'id' => 'int',
'name' => 'string'
diff --git a/samples/client/petstore/perl/lib/WWW/SwaggerClient/Object/Order.pm b/samples/client/petstore/perl/lib/WWW/SwaggerClient/Object/Order.pm
index 70b3db2cfc00..ea5f6160ee5f 100644
--- a/samples/client/petstore/perl/lib/WWW/SwaggerClient/Object/Order.pm
+++ b/samples/client/petstore/perl/lib/WWW/SwaggerClient/Object/Order.pm
@@ -19,6 +19,57 @@ use base "WWW::SwaggerClient::Object::BaseObject";
#NOTE: This class is auto generated by the swagger code generator program. Do not edit the class manually.
#
+__PACKAGE__->class_documentation({description => '',
+ class => 'Order',
+ required => [], # TODO
+} );
+
+__PACKAGE__->method_documentation({
+ 'id' => {
+ datatype => 'int',
+ base_name => 'id',
+ description => '',
+ format => '',
+ read_only => '',
+ },
+ 'pet_id' => {
+ datatype => 'int',
+ base_name => 'petId',
+ description => '',
+ format => '',
+ read_only => '',
+ },
+ 'quantity' => {
+ datatype => 'int',
+ base_name => 'quantity',
+ description => '',
+ format => '',
+ read_only => '',
+ },
+ 'ship_date' => {
+ datatype => 'DateTime',
+ base_name => 'shipDate',
+ description => '',
+ format => '',
+ read_only => '',
+ },
+ 'status' => {
+ datatype => 'string',
+ base_name => 'status',
+ description => 'Order Status',
+ format => '',
+ read_only => '',
+ },
+ 'complete' => {
+ datatype => 'boolean',
+ base_name => 'complete',
+ description => '',
+ format => '',
+ read_only => '',
+ },
+
+});
+
__PACKAGE__->swagger_types( {
'id' => 'int',
'pet_id' => 'int',
diff --git a/samples/client/petstore/perl/lib/WWW/SwaggerClient/Object/Pet.pm b/samples/client/petstore/perl/lib/WWW/SwaggerClient/Object/Pet.pm
index 3ff3f50b3999..a1aeb1341784 100644
--- a/samples/client/petstore/perl/lib/WWW/SwaggerClient/Object/Pet.pm
+++ b/samples/client/petstore/perl/lib/WWW/SwaggerClient/Object/Pet.pm
@@ -19,6 +19,57 @@ use base "WWW::SwaggerClient::Object::BaseObject";
#NOTE: This class is auto generated by the swagger code generator program. Do not edit the class manually.
#
+__PACKAGE__->class_documentation({description => '',
+ class => 'Pet',
+ required => [], # TODO
+} );
+
+__PACKAGE__->method_documentation({
+ 'id' => {
+ datatype => 'int',
+ base_name => 'id',
+ description => '',
+ format => '',
+ read_only => '',
+ },
+ 'category' => {
+ datatype => 'Category',
+ base_name => 'category',
+ description => '',
+ format => '',
+ read_only => '',
+ },
+ 'name' => {
+ datatype => 'string',
+ base_name => 'name',
+ description => '',
+ format => '',
+ read_only => '',
+ },
+ 'photo_urls' => {
+ datatype => 'ARRAY[string]',
+ base_name => 'photoUrls',
+ description => '',
+ format => '',
+ read_only => '',
+ },
+ 'tags' => {
+ datatype => 'ARRAY[Tag]',
+ base_name => 'tags',
+ description => '',
+ format => '',
+ read_only => '',
+ },
+ 'status' => {
+ datatype => 'string',
+ base_name => 'status',
+ description => 'pet status in the store',
+ format => '',
+ read_only => '',
+ },
+
+});
+
__PACKAGE__->swagger_types( {
'id' => 'int',
'category' => 'Category',
diff --git a/samples/client/petstore/perl/lib/WWW/SwaggerClient/Object/Tag.pm b/samples/client/petstore/perl/lib/WWW/SwaggerClient/Object/Tag.pm
index bf97f210a379..a50eded7cde0 100644
--- a/samples/client/petstore/perl/lib/WWW/SwaggerClient/Object/Tag.pm
+++ b/samples/client/petstore/perl/lib/WWW/SwaggerClient/Object/Tag.pm
@@ -19,6 +19,29 @@ use base "WWW::SwaggerClient::Object::BaseObject";
#NOTE: This class is auto generated by the swagger code generator program. Do not edit the class manually.
#
+__PACKAGE__->class_documentation({description => '',
+ class => 'Tag',
+ required => [], # TODO
+} );
+
+__PACKAGE__->method_documentation({
+ 'id' => {
+ datatype => 'int',
+ base_name => 'id',
+ description => '',
+ format => '',
+ read_only => '',
+ },
+ 'name' => {
+ datatype => 'string',
+ base_name => 'name',
+ description => '',
+ format => '',
+ read_only => '',
+ },
+
+});
+
__PACKAGE__->swagger_types( {
'id' => 'int',
'name' => 'string'
diff --git a/samples/client/petstore/perl/lib/WWW/SwaggerClient/Object/User.pm b/samples/client/petstore/perl/lib/WWW/SwaggerClient/Object/User.pm
index 36fc7baf6ee5..cb431b1e059f 100644
--- a/samples/client/petstore/perl/lib/WWW/SwaggerClient/Object/User.pm
+++ b/samples/client/petstore/perl/lib/WWW/SwaggerClient/Object/User.pm
@@ -19,6 +19,71 @@ use base "WWW::SwaggerClient::Object::BaseObject";
#NOTE: This class is auto generated by the swagger code generator program. Do not edit the class manually.
#
+__PACKAGE__->class_documentation({description => '',
+ class => 'User',
+ required => [], # TODO
+} );
+
+__PACKAGE__->method_documentation({
+ 'id' => {
+ datatype => 'int',
+ base_name => 'id',
+ description => '',
+ format => '',
+ read_only => '',
+ },
+ 'username' => {
+ datatype => 'string',
+ base_name => 'username',
+ description => '',
+ format => '',
+ read_only => '',
+ },
+ 'first_name' => {
+ datatype => 'string',
+ base_name => 'firstName',
+ description => '',
+ format => '',
+ read_only => '',
+ },
+ 'last_name' => {
+ datatype => 'string',
+ base_name => 'lastName',
+ description => '',
+ format => '',
+ read_only => '',
+ },
+ 'email' => {
+ datatype => 'string',
+ base_name => 'email',
+ description => '',
+ format => '',
+ read_only => '',
+ },
+ 'password' => {
+ datatype => 'string',
+ base_name => 'password',
+ description => '',
+ format => '',
+ read_only => '',
+ },
+ 'phone' => {
+ datatype => 'string',
+ base_name => 'phone',
+ description => '',
+ format => '',
+ read_only => '',
+ },
+ 'user_status' => {
+ datatype => 'int',
+ base_name => 'userStatus',
+ description => 'User Status',
+ format => '',
+ read_only => '',
+ },
+
+});
+
__PACKAGE__->swagger_types( {
'id' => 'int',
'username' => 'string',
diff --git a/samples/client/petstore/perl/lib/WWW/SwaggerClient/PetApi.pm b/samples/client/petstore/perl/lib/WWW/SwaggerClient/PetApi.pm
index 26b9f42e620e..06ccfca98e80 100644
--- a/samples/client/petstore/perl/lib/WWW/SwaggerClient/PetApi.pm
+++ b/samples/client/petstore/perl/lib/WWW/SwaggerClient/PetApi.pm
@@ -30,11 +30,14 @@ use Log::Any qw($log);
use WWW::SwaggerClient::ApiClient;
use WWW::SwaggerClient::Configuration;
+use base "Class::Data::Inheritable";
+
+__PACKAGE__->mk_classdata('method_documentation' => {});
+
sub new {
my $class = shift;
- my $default_api_client = $WWW::SwaggerClient::Configuration::api_client ? $WWW::SwaggerClient::Configuration::api_client : WWW::SwaggerClient::ApiClient->new;
my (%self) = (
- 'api_client' => $default_api_client,
+ 'api_client' => WWW::SwaggerClient::ApiClient->instance,
@_
);
@@ -47,12 +50,27 @@ sub new {
}
+
#
# update_pet
#
# Update an existing pet
#
# @param Pet $body Pet object that needs to be added to the store (optional)
+{
+ my $params = {
+ 'body' => {
+ data_type => 'Pet',
+ description => 'Pet object that needs to be added to the store',
+ required => '0',
+ },
+ };
+ __PACKAGE__->method_documentation->{ update_pet } = {
+ summary => 'Update an existing pet',
+ params => $params,
+ returns => undef,
+ };
+}
# @return void
#
sub update_pet {
@@ -87,7 +105,7 @@ sub update_pet {
}
# authentication setting, if any
- my $auth_settings = ['petstore_auth'];
+ my $auth_settings = [qw(petstore_auth )];
# make the API Call
@@ -97,12 +115,27 @@ sub update_pet {
return;
}
+
#
# add_pet
#
# Add a new pet to the store
#
# @param Pet $body Pet object that needs to be added to the store (optional)
+{
+ my $params = {
+ 'body' => {
+ data_type => 'Pet',
+ description => 'Pet object that needs to be added to the store',
+ required => '0',
+ },
+ };
+ __PACKAGE__->method_documentation->{ add_pet } = {
+ summary => 'Add a new pet to the store',
+ params => $params,
+ returns => undef,
+ };
+}
# @return void
#
sub add_pet {
@@ -137,7 +170,7 @@ sub add_pet {
}
# authentication setting, if any
- my $auth_settings = ['petstore_auth'];
+ my $auth_settings = [qw(petstore_auth )];
# make the API Call
@@ -147,12 +180,27 @@ sub add_pet {
return;
}
+
#
# find_pets_by_status
#
# Finds Pets by status
#
# @param ARRAY[string] $status Status values that need to be considered for filter (optional)
+{
+ my $params = {
+ 'status' => {
+ data_type => 'ARRAY[string]',
+ description => 'Status values that need to be considered for filter',
+ required => '0',
+ },
+ };
+ __PACKAGE__->method_documentation->{ find_pets_by_status } = {
+ summary => 'Finds Pets by status',
+ params => $params,
+ returns => 'ARRAY[Pet]',
+ };
+}
# @return ARRAY[Pet]
#
sub find_pets_by_status {
@@ -187,7 +235,7 @@ sub find_pets_by_status {
# authentication setting, if any
- my $auth_settings = ['petstore_auth'];
+ my $auth_settings = [qw(petstore_auth )];
# make the API Call
my $response = $self->{api_client}->call_api($_resource_path, $_method,
@@ -200,12 +248,27 @@ sub find_pets_by_status {
return $_response_object;
}
+
#
# find_pets_by_tags
#
# Finds Pets by tags
#
# @param ARRAY[string] $tags Tags to filter by (optional)
+{
+ my $params = {
+ 'tags' => {
+ data_type => 'ARRAY[string]',
+ description => 'Tags to filter by',
+ required => '0',
+ },
+ };
+ __PACKAGE__->method_documentation->{ find_pets_by_tags } = {
+ summary => 'Finds Pets by tags',
+ params => $params,
+ returns => 'ARRAY[Pet]',
+ };
+}
# @return ARRAY[Pet]
#
sub find_pets_by_tags {
@@ -240,7 +303,7 @@ sub find_pets_by_tags {
# authentication setting, if any
- my $auth_settings = ['petstore_auth'];
+ my $auth_settings = [qw(petstore_auth )];
# make the API Call
my $response = $self->{api_client}->call_api($_resource_path, $_method,
@@ -253,12 +316,27 @@ sub find_pets_by_tags {
return $_response_object;
}
+
#
# get_pet_by_id
#
# Find pet by ID
#
# @param int $pet_id ID of pet that needs to be fetched (required)
+{
+ my $params = {
+ 'pet_id' => {
+ data_type => 'int',
+ description => 'ID of pet that needs to be fetched',
+ required => '1',
+ },
+ };
+ __PACKAGE__->method_documentation->{ get_pet_by_id } = {
+ summary => 'Find pet by ID',
+ params => $params,
+ returns => 'Pet',
+ };
+}
# @return Pet
#
sub get_pet_by_id {
@@ -300,7 +378,7 @@ sub get_pet_by_id {
# authentication setting, if any
- my $auth_settings = ['api_key'];
+ my $auth_settings = [qw(api_key )];
# make the API Call
my $response = $self->{api_client}->call_api($_resource_path, $_method,
@@ -313,6 +391,7 @@ sub get_pet_by_id {
return $_response_object;
}
+
#
# update_pet_with_form
#
@@ -321,6 +400,30 @@ sub get_pet_by_id {
# @param string $pet_id ID of pet that needs to be updated (required)
# @param string $name Updated name of the pet (optional)
# @param string $status Updated status of the pet (optional)
+{
+ my $params = {
+ 'pet_id' => {
+ data_type => 'string',
+ description => 'ID of pet that needs to be updated',
+ required => '1',
+ },
+ 'name' => {
+ data_type => 'string',
+ description => 'Updated name of the pet',
+ required => '0',
+ },
+ 'status' => {
+ data_type => 'string',
+ description => 'Updated status of the pet',
+ required => '0',
+ },
+ };
+ __PACKAGE__->method_documentation->{ update_pet_with_form } = {
+ summary => 'Updates a pet in the store with form data',
+ params => $params,
+ returns => undef,
+ };
+}
# @return void
#
sub update_pet_with_form {
@@ -372,7 +475,7 @@ sub update_pet_with_form {
# authentication setting, if any
- my $auth_settings = ['petstore_auth'];
+ my $auth_settings = [qw(petstore_auth )];
# make the API Call
@@ -382,6 +485,7 @@ sub update_pet_with_form {
return;
}
+
#
# delete_pet
#
@@ -389,6 +493,25 @@ sub update_pet_with_form {
#
# @param int $pet_id Pet id to delete (required)
# @param string $api_key (optional)
+{
+ my $params = {
+ 'pet_id' => {
+ data_type => 'int',
+ description => 'Pet id to delete',
+ required => '1',
+ },
+ 'api_key' => {
+ data_type => 'string',
+ description => '',
+ required => '0',
+ },
+ };
+ __PACKAGE__->method_documentation->{ delete_pet } = {
+ summary => 'Deletes a pet',
+ params => $params,
+ returns => undef,
+ };
+}
# @return void
#
sub delete_pet {
@@ -433,7 +556,7 @@ sub delete_pet {
# authentication setting, if any
- my $auth_settings = ['petstore_auth'];
+ my $auth_settings = [qw(petstore_auth )];
# make the API Call
@@ -443,6 +566,7 @@ sub delete_pet {
return;
}
+
#
# upload_file
#
@@ -451,6 +575,30 @@ sub delete_pet {
# @param int $pet_id ID of pet to update (required)
# @param string $additional_metadata Additional data to pass to server (optional)
# @param file $file file to upload (optional)
+{
+ my $params = {
+ 'pet_id' => {
+ data_type => 'int',
+ description => 'ID of pet to update',
+ required => '1',
+ },
+ 'additional_metadata' => {
+ data_type => 'string',
+ description => 'Additional data to pass to server',
+ required => '0',
+ },
+ 'file' => {
+ data_type => 'file',
+ description => 'file to upload',
+ required => '0',
+ },
+ };
+ __PACKAGE__->method_documentation->{ upload_file } = {
+ summary => 'uploads an image',
+ params => $params,
+ returns => undef,
+ };
+}
# @return void
#
sub upload_file {
@@ -503,7 +651,7 @@ sub upload_file {
# authentication setting, if any
- my $auth_settings = ['petstore_auth'];
+ my $auth_settings = [qw(petstore_auth )];
# make the API Call
diff --git a/samples/client/petstore/perl/lib/WWW/SwaggerClient/Role.pm b/samples/client/petstore/perl/lib/WWW/SwaggerClient/Role.pm
new file mode 100644
index 000000000000..feb5228cb615
--- /dev/null
+++ b/samples/client/petstore/perl/lib/WWW/SwaggerClient/Role.pm
@@ -0,0 +1,323 @@
+package WWW::SwaggerClient::Role;
+use utf8;
+
+use Moose::Role;
+use namespace::autoclean;
+use Class::Inspector;
+use Log::Any qw($log);
+use WWW::SwaggerClient::ApiFactory;
+
+has base_url => ( is => 'ro',
+ required => 0,
+ isa => 'Str',
+ documentation => 'Root of the server that requests are sent to',
+ );
+
+has api_factory => ( is => 'ro',
+ isa => 'WWW::SwaggerClient::ApiFactory',
+ builder => '_build_af',
+ lazy => 1,
+ documentation => 'Builds an instance of the endpoint API class',
+ );
+
+has tokens => ( is => 'ro',
+ isa => 'HashRef',
+ required => 0,
+ default => sub { {} },
+ documentation => 'The auth tokens required by the application - basic, OAuth and/or API key(s)',
+ );
+
+has _cfg => ( is => 'ro',
+ isa => 'Str',
+ default => 'WWW::SwaggerClient::Configuration',
+ );
+
+has version_info => ( is => 'ro',
+ isa => 'HashRef',
+ default => sub { {
+ app_name => 'Swagger Petstore',
+ app_version => '1.0.0',
+ generated_date => '2015-11-13T20:46:43.271Z',
+ generator_class => 'class io.swagger.codegen.languages.PerlClientCodegen',
+ } },
+ documentation => 'Information about the application version and the codegen codebase version'
+ );
+
+sub BUILD {
+ my $self = shift;
+
+ $self->_cfg->accept_tokens( $self->tokens ) if keys %{$self->tokens};
+
+ # ignore these symbols imported into API namespaces
+ my %outsiders = map {$_ => 1} qw( croak );
+
+ my %delegates;
+
+ # collect the methods callable on each API
+ foreach my $api_name ($self->api_factory->apis_available) {
+ my $api_class = $self->api_factory->classname_for($api_name);
+ my $methods = Class::Inspector->methods($api_class, 'expanded'); # not Moose, so use CI instead
+ my @local_methods = grep {! /^_/} grep {! $outsiders{$_}} map {$_->[2]} grep {$_->[1] eq $api_class} @$methods;
+ push( @{$delegates{$_}}, {api_name => $api_name, api_class => $api_class} ) for @local_methods;
+ }
+
+ # remove clashes
+ foreach my $method (keys %delegates) {
+ if ( @{$delegates{$method}} > 1 ) {
+ my ($apis) = delete $delegates{$method};
+ }
+ }
+
+ # build the flattened API
+ foreach my $api_name ($self->api_factory->apis_available) {
+ my $att_name = sprintf "%s_api", lc($api_name);
+ my $api_class = $self->api_factory->classname_for($api_name);
+ my @delegated = grep { $delegates{$_}->[0]->{api_name} eq $api_name } keys %delegates;
+ $log->debugf("Adding API: '%s' handles %s", $att_name, join ', ', @delegated);
+ $self->meta->add_attribute( $att_name => (
+ is => 'ro',
+ isa => $api_class,
+ default => sub {$self->api_factory->get_api($api_name)},
+ lazy => 1,
+ handles => \@delegated,
+ ) );
+ }
+}
+
+sub _build_af {
+ my $self = shift;
+ my %args;
+ $args{base_url} = $self->base_url if $self->base_url;
+ return WWW::SwaggerClient::ApiFactory->new(%args);
+}
+
+=head1 NAME
+
+WWW::SwaggerClient::Role - a Moose role for the Swagger Petstore
+
+=head2 Swagger Petstore version: 1.0.0
+
+=head1 VERSION
+
+Automatically generated by the Perl Swagger Codegen project:
+
+=over 4
+
+=item Build date: 2015-11-13T20:46:43.271Z
+
+=item Build package: class io.swagger.codegen.languages.PerlClientCodegen
+
+=item Codegen version:
+
+=back
+
+=head2 A note on Moose
+
+This role is the only component of the library that uses Moose. See
+WWW::SwaggerClient::ApiFactory for non-Moosey usage.
+
+=head1 SYNOPSIS
+
+The Perl Swagger Codegen project builds a library of Perl modules to interact with
+a web service defined by a Swagger specification. See below for how to build the
+library.
+
+This module provides an interface to the generated library. All the classes,
+objects, and methods (well, not quite *all*, see below) are flattened into this
+role.
+
+ package MyApp;
+ use Moose;
+ with 'WWW::SwaggerClient::Role';
+
+ package main;
+
+ my $api = MyApp->new({ tokens => $tokens });
+
+ my $pet = $api->get_pet_by_id(pet_id => $pet_id);
+
+=head2 Structure of the library
+
+The library consists of a set of API classes, one for each endpoint. These APIs
+implement the method calls available on each endpoint.
+
+Additionally, there is a set of "object" classes, which represent the objects
+returned by and sent to the methods on the endpoints.
+
+An API factory class is provided, which builds instances of each endpoint API.
+
+This Moose role flattens all the methods from the endpoint APIs onto the consuming
+class. It also provides methods to retrieve the endpoint API objects, and the API
+factory object, should you need it.
+
+For documentation of all these methods, see AUTOMATIC DOCUMENTATION below.
+
+=head2 Configuring authentication
+
+In the normal case, the Swagger spec will describe what parameters are
+required and where to put them. You just need to supply the tokens.
+
+ my $tokens = {
+ # basic
+ username => $username,
+ password => $password,
+
+ # oauth
+ access_token => $oauth_token,
+
+ # keys
+ $some_key => { token => $token,
+ prefix => $prefix,
+ in => $in, # 'head||query',
+ },
+
+ $another => { token => $token,
+ prefix => $prefix,
+ in => $in, # 'head||query',
+ },
+ ...,
+
+ };
+
+ my $api = MyApp->new({ tokens => $tokens });
+
+Note these are all optional, as are C and C, and depend on the API
+you are accessing. Usually C and C will be determined by the code generator from
+the spec and you will not need to set them at run time. If not, C will
+default to 'head' and C to the empty string.
+
+The tokens will be placed in the C namespace
+as follows, but you don't need to know about this.
+
+=over 4
+
+=item C<$WWW::SwaggerClient::Configuration::username>
+
+String. The username for basic auth.
+
+=item C<$WWW::SwaggerClient::Configuration::password>
+
+String. The password for basic auth.
+
+=item C<$WWW::SwaggerClient::Configuration::api_key>
+
+Hashref. Keyed on the name of each key (there can be multiple tokens).
+
+ $WWW::SwaggerClient::Configuration::api_key = {
+ secretKey => 'aaaabbbbccccdddd',
+ anotherKey => '1111222233334444',
+ };
+
+=item C<$WWW::SwaggerClient::Configuration::api_key_prefix>
+
+Hashref. Keyed on the name of each key (there can be multiple tokens). Note not
+all api keys require a prefix.
+
+ $WWW::SwaggerClient::Configuration::api_key_prefix = {
+ secretKey => 'string',
+ anotherKey => 'same or some other string',
+ };
+
+=item C<$WWW::SwaggerClient::Configuration::access_token>
+
+String. The OAuth access token.
+
+=back
+
+=head1 METHODS
+
+=head2 C
+
+The generated code has the C already set as a default value. This method
+returns (and optionally sets, but only if the API client has not been
+created yet) the current value of C.
+
+=head2 C
+
+Returns an API factory object. You probably won't need to call this directly.
+
+ $self->api_factory('Pet'); # returns a WWW::SwaggerClient::PetApi instance
+
+ $self->pet_api; # the same
+
+=head1 MISSING METHODS
+
+Most of the methods on the API are delegated to individual endpoint API objects
+(e.g. Pet API, Store API, User API etc). Where different endpoint APIs use the
+same method name (e.g. C), these methods can't be delegated. So you need
+to call C<$api-Epet_api-Enew()>.
+
+In principle, every API is susceptible to the presence of a few, random, undelegatable
+method names. In practice, because of the way method names are constructed, it's
+unlikely in general that any methods will be undelegatable, except for:
+
+ new()
+ class_documentation()
+ method_documentation()
+
+To call these methods, you need to get a handle on the relevant object, either
+by calling C<$api-Efoo_api> or by retrieving an object, e.g.
+C<$api-Eget_pet_by_id(pet_id =E $pet_id)>. They are class methods, so
+you could also call them on class names.
+
+=head1 BUILDING YOUR LIBRARY
+
+See the homepage C for full details.
+But briefly, clone the git repository, build the codegen codebase, set up your build
+config file, then run the API build script. You will need git, Java 7 and Apache
+maven 3.0.3 or better already installed.
+
+The config file should specify the project name for the generated library:
+
+ {"moduleName":"MyProjectName"}
+
+Your library files will be built under C.
+
+ $ git clone https://github.com/swagger-api/swagger-codegen.git
+ $ cd swagger-codegen
+ $ mvn package
+ $ java -jar modules/swagger-codegen-cli/target/swagger-codegen-cli.jar generate \
+ -i [URL or file path to JSON swagger API spec] \
+ -l perl \
+ -c /path/to/config/file.json \
+ -o /path/to/output/folder
+
+Bang, all done. Run the C script in the C directory to see the API
+you just built.
+
+=head1 AUTOMATIC DOCUMENTATION
+
+You can print out a summary of the generated API by running the included
+C script in the C directory of your generated library. A few
+output formats are supported:
+
+ Usage: autodoc [OPTION]
+
+ -w wide format (default)
+ -n narrow format
+ -p POD format
+ -H HTML format
+ -m Markdown format
+ -h print this help message
+ -c your application class
+
+The C<-c> option allows you to load and inspect your own application. A dummy
+namespace is used if you don't supply your own class.
+
+=head1 DOCUMENTATION FROM THE SWAGGER SPEC
+
+Additional documentation for each class and method may be provided by the Swagger
+spec. If so, this is available via the C and
+C methods on each generated object class, and the
+C method on the endpoint API classes:
+
+ my $cmdoc = $api->pet_api->method_documentation->{$method_name};
+
+ my $odoc = $api->get_pet_by_id->(pet_id => $pet_id)->class_documentation;
+ my $omdoc = $api->get_pet_by_id->(pet_id => $pet_id)->method_documentation->{method_name};
+
+Each of these calls returns a hashref with various useful pieces of information.
+
+=cut
+
+1;
diff --git a/samples/client/petstore/perl/lib/WWW/SwaggerClient/Role/AutoDoc.pm b/samples/client/petstore/perl/lib/WWW/SwaggerClient/Role/AutoDoc.pm
new file mode 100644
index 000000000000..0dc30dbfb902
--- /dev/null
+++ b/samples/client/petstore/perl/lib/WWW/SwaggerClient/Role/AutoDoc.pm
@@ -0,0 +1,427 @@
+package WWW::SwaggerClient::Role::AutoDoc;
+use List::MoreUtils qw(uniq);
+
+use Moose::Role;
+
+sub autodoc {
+ my ($self, $how) = @_;
+
+ die "Unknown format '$how'" unless $how =~ /^(pod|wide|narrow)$/;
+
+ $self->_printisa($how);
+ $self->_printmethods($how);
+ $self->_printattrs($how);
+ print "\n";
+}
+
+sub _printisa {
+ my ($self, $how) = @_;
+ my $meta = $self->meta;
+
+ my $myclass = ref $self;
+
+ my $super = join ', ', $meta->superclasses;
+ my @roles = $meta->calculate_all_roles;
+ #shift(@roles) if @roles > 1; # if > 1, the first is a composite, the rest are the roles
+
+ my $isa = join ', ', grep {$_ ne $myclass} $meta->linearized_isa;
+ my $sub = join ', ', $meta->subclasses;
+ my $dsub = join ', ', $meta->direct_subclasses;
+
+ my $app_name = $self->version_info->{app_name};
+ my $app_version = $self->version_info->{app_version};
+ my $generated_date = $self->version_info->{generated_date};
+ my $generator_class = $self->version_info->{generator_class};
+
+ $~ = $how eq 'pod' ? 'INHERIT_POD' : 'INHERIT';
+ write;
+
+ my ($rolepkg, $role_reqs);
+
+ foreach my $role (@roles) {
+ $rolepkg = $role->{package} || next; # some are anonymous, or something
+ next if $rolepkg eq 'WWW::SwaggerClient::Role::AutoDoc';
+ $role_reqs = join ', ', keys %{$role->{required_methods}};
+ $role_reqs ||= '';
+ $~ = $how eq 'pod' ? 'ROLES_POD' : 'ROLES';
+ write;
+ }
+
+ if ($how eq 'pod') {
+ $~ = 'ROLES_POD_CLOSE';
+ write;
+ }
+
+# ----- format specs -----
+ format INHERIT =
+
+@* -
+$myclass
+ ISA: @*
+ $isa
+ Direct subclasses: @*
+ $dsub
+ All subclasses: @*
+ $sub
+
+ Target API: @* @*
+ $app_name, $app_version
+ Generated on: @*
+ $generated_date
+ Generator class: @*
+ $generator_class
+
+.
+ format ROLES =
+ Composes: ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< ~
+ $rolepkg
+ requires: ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< ~
+ $role_reqs
+ ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< ~~
+ $role_reqs
+.
+
+ format INHERIT_POD =
+=head1 NAME
+
+@*
+$myclass
+
+=head1 VERSION
+
+=head2 @* version: @*
+ $app_name, $app_version
+
+Automatically generated by the Perl Swagger Codegen project:
+
+=over 4
+
+=item Build date: @*
+ $generated_date
+
+=item Build package: @*
+ $generator_class
+
+=item Codegen version:
+
+
+=back
+
+=head1 INHERITANCE
+
+=head2 Base class(es)
+
+@*
+$isa
+
+=head2 Direct subclasses
+
+@*
+$dsub
+
+=head2 All subclasses
+
+@*
+$sub
+
+
+=head1 COMPOSITION
+
+@* composes the following roles:
+$myclass
+
+
+.
+ format ROLES_POD =
+=head2 C<@*>
+ $rolepkg
+
+Requires:
+
+@*
+$role_reqs
+
+.
+ format ROLES_POD_CLOSE =
+
+
+.
+# ----- / format specs -----
+}
+
+sub _printmethods {
+ my ($self, $how) = @_;
+
+ if ($how eq 'narrow') {
+ print <_printmethod($_, $how) for uniq sort $self->meta->get_all_method_names; #$self->meta->get_method_list,
+
+ if ($how eq 'pod') {
+ $~ = 'METHOD_POD_CLOSE';
+ write;
+ }
+
+
+}
+
+sub _printmethod {
+ my ($self, $methodname, $how) = @_;
+ return if $methodname =~ /^_/;
+ return if $self->meta->has_attribute($methodname);
+ my %internal = map {$_ => 1} qw(BUILD BUILDARGS meta can new DEMOLISHALL DESTROY
+ DOES isa BUILDALL does VERSION dump
+ );
+ return if $internal{$methodname};
+ my $method = $self->meta->get_method($methodname) or return; # symbols imported into namespaces i.e. not known by Moose
+
+ return if $method->original_package_name eq __PACKAGE__;
+
+ my $delegate_to = '';
+ my $via = '';
+ my $on = '';
+ my $doc = '';
+ my $original_pkg = $method->original_package_name;
+ if ($method->can('associated_attribute')) {
+ $delegate_to = $method->delegate_to_method;
+ my $aa = $method->associated_attribute;
+ $on = $aa->{isa};
+ $via = $aa->{name};
+ $original_pkg = $on;
+ $doc = $original_pkg->method_documentation->{$delegate_to}->{summary};
+ }
+ else {
+ $doc = $method->documentation;
+ }
+
+ if ($how eq 'narrow') {
+ $~ = 'METHOD_NARROW';
+ write;
+ }
+ elsif ($how eq 'pod' and $delegate_to) {
+ $~ = 'METHOD_POD_DELEGATED';
+ write;
+ }
+ elsif ($how eq 'pod') {
+ $~ = 'METHOD_POD';
+ write;
+ }
+ else {
+ $~ = 'METHOD';
+ write;
+ }
+
+# ----- format specs -----
+ format METHODHEAD =
+
+METHODS
+-------
+Name delegates to on via
+===========================================================================================================================================================================
+.
+ format METHOD =
+@<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< @<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<... @<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<... @<<<<<<<<<<<<<<<<...
+$methodname, $delegate_to, $on, $via
+.
+
+ format METHOD_NARROW =
+@*
+$methodname
+ original pkg: @*
+ $original_pkg
+ delegates to: @*
+ $delegate_to
+ on: @*
+ $on
+ via: @*
+ $via
+
+.
+
+ format METHODHEAD_POD =
+
+=head1 METHODS
+
+.
+
+ format METHOD_POD =
+
+=head2 C<@*()>
+ $methodname
+
+ Defined in: @*
+ $original_pkg
+
+
+.
+ format METHOD_POD_DELEGATED =
+
+=head2 C<@*()>
+ $methodname
+
+ Defined in: @*
+ $original_pkg
+ Delegates to: @*()
+ $delegate_to
+ On: @*
+ $on
+ Via: @*()
+ $via
+ Doc: @*
+ $doc
+ Same as: $self->@*->@*()
+ $via, $delegate_to
+
+.
+ format METHOD_POD_CLOSE =
+
+.
+# ----- / format specs -----
+}
+
+sub _printattrs {
+ my ($self, $how) = @_;
+
+ if ($how eq 'narrow') {
+ print <_printattr($_, $how) for sort $self->meta->get_attribute_list;
+
+ if ($how eq 'pod') {
+ $~ = 'ATTR_POD_CLOSE';
+ write;
+ }
+}
+
+sub _printattr {
+ my ($self, $attrname, $how) = @_;
+ return if $attrname =~ /^_/;
+ my $attr = $self->meta->get_attribute($attrname) or die "No attr for $attrname";
+
+ my $is;
+ $is = 'rw' if $attr->get_read_method && $attr->get_write_method;
+ $is = 'ro' if $attr->get_read_method && ! $attr->get_write_method;
+ $is = 'wo' if $attr->get_write_method && ! $attr->get_read_method;
+ $is = '--' if ! $attr->get_write_method && ! $attr->get_read_method;
+ $is or die "No \$is for $attrname";
+
+ my $tc = $attr->type_constraint || '';
+ my $from = $attr->associated_class->name || '';
+ my $reqd = $attr->is_required ? 'yes' : 'no';
+ my $lazy = $attr->is_lazy ? 'yes' : 'no';
+ my $has_doc = $attr->has_documentation ? 'yes' : 'no'; # *_api attributes will never have doc, but other attributes might have
+ my $doc = $attr->documentation || '';
+ my $handles = join ', ', sort @{$attr->handles || []};
+ $handles ||= '';
+
+ if ($how eq 'narrow') {
+ $~ = 'ATTR_NARROW';
+ }
+ elsif ($how eq 'pod') {
+ $~ = 'ATTR_POD';
+ }
+ else {
+ $~ = 'ATTR';
+ }
+
+ write;
+
+# ----- format specs -----
+ format ATTRHEAD =
+
+ATTRIBUTES
+----------
+Name is isa reqd lazy doc handles
+==============================================================================================================
+.
+ format ATTR =
+@<<<<<<<<<<<<<<<<< @< @<<<<<<<<<<<<<<<<<<<<<<<< @<<< @<<< @<< ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
+$attrname, $is, $tc, $reqd, $lazy, $has_doc, $handles
+ ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< ~~
+ $handles
+.
+
+ format ATTR_NARROW =
+@*
+$attrname
+ is: @*
+ $is
+ isa: @*
+ $tc
+ reqd: @*
+ $reqd
+ lazy: @*
+ $lazy
+ doc: @*
+ $doc
+ handles: ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
+ $handles
+ ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< ~~
+ $handles
+
+.
+ format ATTRHEAD_POD =
+=head1 ATTRIBUTES
+
+.
+ format ATTR_POD =
+
+=head2 C<@*>
+ $attrname
+
+ is: @*
+ $is
+ isa: @*
+ $tc
+ reqd: @*
+ $reqd
+ lazy: @*
+ $lazy
+ doc: @*
+ $doc
+ handles: ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
+ $handles
+ ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< ~~
+ $handles
+
+.
+ format ATTR_POD_CLOSE =
+
+
+.
+# ----- / format specs -----
+}
+
+
+
+1;
\ No newline at end of file
diff --git a/samples/client/petstore/perl/lib/WWW/SwaggerClient/StoreApi.pm b/samples/client/petstore/perl/lib/WWW/SwaggerClient/StoreApi.pm
index a2ac9010e779..abe936573e7c 100644
--- a/samples/client/petstore/perl/lib/WWW/SwaggerClient/StoreApi.pm
+++ b/samples/client/petstore/perl/lib/WWW/SwaggerClient/StoreApi.pm
@@ -30,11 +30,14 @@ use Log::Any qw($log);
use WWW::SwaggerClient::ApiClient;
use WWW::SwaggerClient::Configuration;
+use base "Class::Data::Inheritable";
+
+__PACKAGE__->mk_classdata('method_documentation' => {});
+
sub new {
my $class = shift;
- my $default_api_client = $WWW::SwaggerClient::Configuration::api_client ? $WWW::SwaggerClient::Configuration::api_client : WWW::SwaggerClient::ApiClient->new;
my (%self) = (
- 'api_client' => $default_api_client,
+ 'api_client' => WWW::SwaggerClient::ApiClient->instance,
@_
);
@@ -47,11 +50,21 @@ sub new {
}
+
#
# get_inventory
#
# Returns pet inventories by status
#
+{
+ my $params = {
+ };
+ __PACKAGE__->method_documentation->{ get_inventory } = {
+ summary => 'Returns pet inventories by status',
+ params => $params,
+ returns => 'HASH[string,int]',
+ };
+}
# @return HASH[string,int]
#
sub get_inventory {
@@ -83,7 +96,7 @@ sub get_inventory {
# authentication setting, if any
- my $auth_settings = ['api_key'];
+ my $auth_settings = [qw(api_key )];
# make the API Call
my $response = $self->{api_client}->call_api($_resource_path, $_method,
@@ -96,12 +109,27 @@ sub get_inventory {
return $_response_object;
}
+
#
# place_order
#
# Place an order for a pet
#
# @param Order $body order placed for purchasing the pet (optional)
+{
+ my $params = {
+ 'body' => {
+ data_type => 'Order',
+ description => 'order placed for purchasing the pet',
+ required => '0',
+ },
+ };
+ __PACKAGE__->method_documentation->{ place_order } = {
+ summary => 'Place an order for a pet',
+ params => $params,
+ returns => 'Order',
+ };
+}
# @return Order
#
sub place_order {
@@ -136,7 +164,7 @@ sub place_order {
}
# authentication setting, if any
- my $auth_settings = [];
+ my $auth_settings = [qw()];
# make the API Call
my $response = $self->{api_client}->call_api($_resource_path, $_method,
@@ -149,12 +177,27 @@ sub place_order {
return $_response_object;
}
+
#
# get_order_by_id
#
# Find purchase order by ID
#
# @param string $order_id ID of pet that needs to be fetched (required)
+{
+ my $params = {
+ 'order_id' => {
+ data_type => 'string',
+ description => 'ID of pet that needs to be fetched',
+ required => '1',
+ },
+ };
+ __PACKAGE__->method_documentation->{ get_order_by_id } = {
+ summary => 'Find purchase order by ID',
+ params => $params,
+ returns => 'Order',
+ };
+}
# @return Order
#
sub get_order_by_id {
@@ -196,7 +239,7 @@ sub get_order_by_id {
# authentication setting, if any
- my $auth_settings = [];
+ my $auth_settings = [qw()];
# make the API Call
my $response = $self->{api_client}->call_api($_resource_path, $_method,
@@ -209,12 +252,27 @@ sub get_order_by_id {
return $_response_object;
}
+
#
# delete_order
#
# Delete purchase order by ID
#
# @param string $order_id ID of the order that needs to be deleted (required)
+{
+ my $params = {
+ 'order_id' => {
+ data_type => 'string',
+ description => 'ID of the order that needs to be deleted',
+ required => '1',
+ },
+ };
+ __PACKAGE__->method_documentation->{ delete_order } = {
+ summary => 'Delete purchase order by ID',
+ params => $params,
+ returns => undef,
+ };
+}
# @return void
#
sub delete_order {
@@ -256,7 +314,7 @@ sub delete_order {
# authentication setting, if any
- my $auth_settings = [];
+ my $auth_settings = [qw()];
# make the API Call
diff --git a/samples/client/petstore/perl/lib/WWW/SwaggerClient/UserApi.pm b/samples/client/petstore/perl/lib/WWW/SwaggerClient/UserApi.pm
index e1088a0839e0..9ba45815c8ce 100644
--- a/samples/client/petstore/perl/lib/WWW/SwaggerClient/UserApi.pm
+++ b/samples/client/petstore/perl/lib/WWW/SwaggerClient/UserApi.pm
@@ -30,11 +30,14 @@ use Log::Any qw($log);
use WWW::SwaggerClient::ApiClient;
use WWW::SwaggerClient::Configuration;
+use base "Class::Data::Inheritable";
+
+__PACKAGE__->mk_classdata('method_documentation' => {});
+
sub new {
my $class = shift;
- my $default_api_client = $WWW::SwaggerClient::Configuration::api_client ? $WWW::SwaggerClient::Configuration::api_client : WWW::SwaggerClient::ApiClient->new;
my (%self) = (
- 'api_client' => $default_api_client,
+ 'api_client' => WWW::SwaggerClient::ApiClient->instance,
@_
);
@@ -47,12 +50,27 @@ sub new {
}
+
#
# create_user
#
# Create user
#
# @param User $body Created user object (optional)
+{
+ my $params = {
+ 'body' => {
+ data_type => 'User',
+ description => 'Created user object',
+ required => '0',
+ },
+ };
+ __PACKAGE__->method_documentation->{ create_user } = {
+ summary => 'Create user',
+ params => $params,
+ returns => undef,
+ };
+}
# @return void
#
sub create_user {
@@ -87,7 +105,7 @@ sub create_user {
}
# authentication setting, if any
- my $auth_settings = [];
+ my $auth_settings = [qw()];
# make the API Call
@@ -97,12 +115,27 @@ sub create_user {
return;
}
+
#
# create_users_with_array_input
#
# Creates list of users with given input array
#
# @param ARRAY[User] $body List of user object (optional)
+{
+ my $params = {
+ 'body' => {
+ data_type => 'ARRAY[User]',
+ description => 'List of user object',
+ required => '0',
+ },
+ };
+ __PACKAGE__->method_documentation->{ create_users_with_array_input } = {
+ summary => 'Creates list of users with given input array',
+ params => $params,
+ returns => undef,
+ };
+}
# @return void
#
sub create_users_with_array_input {
@@ -137,7 +170,7 @@ sub create_users_with_array_input {
}
# authentication setting, if any
- my $auth_settings = [];
+ my $auth_settings = [qw()];
# make the API Call
@@ -147,12 +180,27 @@ sub create_users_with_array_input {
return;
}
+
#
# create_users_with_list_input
#
# Creates list of users with given input array
#
# @param ARRAY[User] $body List of user object (optional)
+{
+ my $params = {
+ 'body' => {
+ data_type => 'ARRAY[User]',
+ description => 'List of user object',
+ required => '0',
+ },
+ };
+ __PACKAGE__->method_documentation->{ create_users_with_list_input } = {
+ summary => 'Creates list of users with given input array',
+ params => $params,
+ returns => undef,
+ };
+}
# @return void
#
sub create_users_with_list_input {
@@ -187,7 +235,7 @@ sub create_users_with_list_input {
}
# authentication setting, if any
- my $auth_settings = [];
+ my $auth_settings = [qw()];
# make the API Call
@@ -197,6 +245,7 @@ sub create_users_with_list_input {
return;
}
+
#
# login_user
#
@@ -204,6 +253,25 @@ sub create_users_with_list_input {
#
# @param string $username The user name for login (optional)
# @param string $password The password for login in clear text (optional)
+{
+ my $params = {
+ 'username' => {
+ data_type => 'string',
+ description => 'The user name for login',
+ required => '0',
+ },
+ 'password' => {
+ data_type => 'string',
+ description => 'The password for login in clear text',
+ required => '0',
+ },
+ };
+ __PACKAGE__->method_documentation->{ login_user } = {
+ summary => 'Logs user into the system',
+ params => $params,
+ returns => 'string',
+ };
+}
# @return string
#
sub login_user {
@@ -241,7 +309,7 @@ sub login_user {
# authentication setting, if any
- my $auth_settings = [];
+ my $auth_settings = [qw()];
# make the API Call
my $response = $self->{api_client}->call_api($_resource_path, $_method,
@@ -254,11 +322,21 @@ sub login_user {
return $_response_object;
}
+
#
# logout_user
#
# Logs out current logged in user session
#
+{
+ my $params = {
+ };
+ __PACKAGE__->method_documentation->{ logout_user } = {
+ summary => 'Logs out current logged in user session',
+ params => $params,
+ returns => undef,
+ };
+}
# @return void
#
sub logout_user {
@@ -290,7 +368,7 @@ sub logout_user {
# authentication setting, if any
- my $auth_settings = [];
+ my $auth_settings = [qw()];
# make the API Call
@@ -300,12 +378,27 @@ sub logout_user {
return;
}
+
#
# get_user_by_name
#
# Get user by user name
#
# @param string $username The name that needs to be fetched. Use user1 for testing. (required)
+{
+ my $params = {
+ 'username' => {
+ data_type => 'string',
+ description => 'The name that needs to be fetched. Use user1 for testing.',
+ required => '1',
+ },
+ };
+ __PACKAGE__->method_documentation->{ get_user_by_name } = {
+ summary => 'Get user by user name',
+ params => $params,
+ returns => 'User',
+ };
+}
# @return User
#
sub get_user_by_name {
@@ -347,7 +440,7 @@ sub get_user_by_name {
# authentication setting, if any
- my $auth_settings = [];
+ my $auth_settings = [qw()];
# make the API Call
my $response = $self->{api_client}->call_api($_resource_path, $_method,
@@ -360,6 +453,7 @@ sub get_user_by_name {
return $_response_object;
}
+
#
# update_user
#
@@ -367,6 +461,25 @@ sub get_user_by_name {
#
# @param string $username name that need to be deleted (required)
# @param User $body Updated user object (optional)
+{
+ my $params = {
+ 'username' => {
+ data_type => 'string',
+ description => 'name that need to be deleted',
+ required => '1',
+ },
+ 'body' => {
+ data_type => 'User',
+ description => 'Updated user object',
+ required => '0',
+ },
+ };
+ __PACKAGE__->method_documentation->{ update_user } = {
+ summary => 'Updated user',
+ params => $params,
+ returns => undef,
+ };
+}
# @return void
#
sub update_user {
@@ -411,7 +524,7 @@ sub update_user {
}
# authentication setting, if any
- my $auth_settings = [];
+ my $auth_settings = [qw()];
# make the API Call
@@ -421,12 +534,27 @@ sub update_user {
return;
}
+
#
# delete_user
#
# Delete user
#
# @param string $username The name that needs to be deleted (required)
+{
+ my $params = {
+ 'username' => {
+ data_type => 'string',
+ description => 'The name that needs to be deleted',
+ required => '1',
+ },
+ };
+ __PACKAGE__->method_documentation->{ delete_user } = {
+ summary => 'Delete user',
+ params => $params,
+ returns => undef,
+ };
+}
# @return void
#
sub delete_user {
@@ -468,7 +596,7 @@ sub delete_user {
# authentication setting, if any
- my $auth_settings = [];
+ my $auth_settings = [qw()];
# make the API Call
diff --git a/samples/client/petstore/perl/pom.xml b/samples/client/petstore/perl/pom.xml
index 4034cf0a6871..4aa0040f82e7 100644
--- a/samples/client/petstore/perl/pom.xml
+++ b/samples/client/petstore/perl/pom.xml
@@ -65,6 +65,19 @@
+
+ Test::More for Role
+ integration-test
+
+ exec
+
+
+ perl
+
+ t/04_role.t
+
+
+
diff --git a/samples/client/petstore/perl/t/01_pet_api.t b/samples/client/petstore/perl/t/01_pet_api.t
index 5460c3282b26..c7bcdf98a0aa 100644
--- a/samples/client/petstore/perl/t/01_pet_api.t
+++ b/samples/client/petstore/perl/t/01_pet_api.t
@@ -1,4 +1,4 @@
-use Test::More tests => 37;
+use Test::More tests => 38;
use Test::Exception;
use lib 'lib';
@@ -11,12 +11,18 @@ use_ok('WWW::SwaggerClient::Object::Pet');
use_ok('WWW::SwaggerClient::Object::Tag');
use_ok('WWW::SwaggerClient::Object::Category');
-my $api_client = WWW::SwaggerClient::ApiClient->new('base_url' => 'http://testing');
+my $api_client = WWW::SwaggerClient::ApiClient->instance('base_url' => 'http://testing');
my $pet_api = WWW::SwaggerClient::PetApi->new('api_client' => $api_client);
is $pet_api->{api_client}->{base_url}, 'http://testing', 'get the proper base URL from api client';
my $api = WWW::SwaggerClient::PetApi->new();
+is $api->{api_client}->{base_url}, 'http://testing', 'we still get the original base URL from api client, because it\'s a singleton';
+
+# reset the base_url - no direct access because an application shouldn't be changing
+# its base URL halfway through
+$api->{api_client}->{base_url} = 'http://petstore.swagger.io/v2';
+
is $api->{api_client}->{base_url}, 'http://petstore.swagger.io/v2', 'get the default base URL from api client';
# test select_header_content_type
diff --git a/samples/client/petstore/perl/t/02_store_api.t b/samples/client/petstore/perl/t/02_store_api.t
index dfee5c468398..39b18381b0e7 100644
--- a/samples/client/petstore/perl/t/02_store_api.t
+++ b/samples/client/petstore/perl/t/02_store_api.t
@@ -15,7 +15,7 @@ use_ok('WWW::SwaggerClient::Object::Category');
use_ok('WWW::SwaggerClient::Object::User');
-my $api_client = WWW::SwaggerClient::ApiClient->new();
+my $api_client = WWW::SwaggerClient::ApiClient->instance();
my $store_api = WWW::SwaggerClient::StoreApi->new('api_client' => $api_client);
is $store_api->{api_client}->{base_url}, 'http://petstore.swagger.io/v2', 'get the default base URL from api client';
diff --git a/samples/client/petstore/perl/t/03_api_factory.t b/samples/client/petstore/perl/t/03_api_factory.t
index f96bffa7a842..a06805e2bcfe 100644
--- a/samples/client/petstore/perl/t/03_api_factory.t
+++ b/samples/client/petstore/perl/t/03_api_factory.t
@@ -1,4 +1,4 @@
-use Test::More tests => 13;
+use Test::More tests => 19;
use Test::Exception;
use lib 'lib';
@@ -15,6 +15,9 @@ is $pet_api->{api_client}->{base_url}, 'http://testing', 'get the proper base UR
$api_factory = WWW::SwaggerClient::ApiFactory->new;
$pet_api = $api_factory->get_api('Pet');
+# reset the base_url - no direct access because an application shouldn't be changing
+# its base URL halfway through
+$pet_api->{api_client}->{base_url} = 'http://petstore.swagger.io/v2';
is $pet_api->{api_client}->{base_url}, 'http://petstore.swagger.io/v2', 'get the default base URL from api client';
# test accessor methods
@@ -32,3 +35,15 @@ is $pet->category->id, '22', 'got the proper category id';
is $pet->category->name, 'perl', 'got the proper category name';
is $pet->tags->[0]->name, 'just kidding', 'got the proper tag name';
is $pet->tags->[0]->id, '11', 'got the proper tag id';
+
+
+my $add_pet = $pet_api->add_pet(body => $pet);
+my $get_pet = $pet_api->get_pet_by_id(pet_id => $pet_id);
+
+is $get_pet->id, '10008', 'stored and retrieved: got the proper pet id';
+is $get_pet->name, 'perl test', 'stored and retrieved: got the proper pet name';
+is $get_pet->category->id, '22', 'stored and retrieved: got the proper category id';
+is $get_pet->category->name, 'perl', 'stored and retrieved: got the proper category name';
+is $get_pet->tags->[0]->name, 'just kidding', 'stored and retrieved: got the proper tag name';
+is $get_pet->tags->[0]->id, '11', 'stored and retrieved: got the proper tag id';
+
diff --git a/samples/client/petstore/perl/t/04_role.t b/samples/client/petstore/perl/t/04_role.t
new file mode 100644
index 000000000000..73328fa6e629
--- /dev/null
+++ b/samples/client/petstore/perl/t/04_role.t
@@ -0,0 +1,143 @@
+use Test::More tests => 37;
+use Test::Exception;
+use Test::Warnings 'warnings';
+use Test::Deep;
+
+use lib 'lib';
+use strict;
+use warnings;
+
+SKIP: {
+ eval "
+ package MyApp;
+ use Moose;
+ with 'WWW::SwaggerClient::Role';
+ sub auth_setup_handler {}
+ ";
+
+# die $@ if $@;
+ skip 'Moose not installed', 37 if $@;
+
+my $api = MyApp->new;
+
+my $pet_id = 10008;
+# note - we don't need to 'use' these modules because they've already been loaded by ApiFactory
+my ($category, $tag, $pet);
+lives_ok { $category = WWW::SwaggerClient::Object::Category->new('id' => '22', 'name' => 'perl') } 'Category.pm loaded OK';
+lives_ok { $tag = WWW::SwaggerClient::Object::Tag->new('id' => '11', 'name' => 'just kidding') } 'Tag.pm loaded OK';
+lives_ok { $pet = WWW::SwaggerClient::Object::Pet->new('id' => $pet_id, 'name' => 'perl test',
+ "photoUrls" => ['123', 'oop'], 'tags' => [$tag], 'status' => 'pending', 'category' => $category) } 'Pet.pm loaded OK';
+
+is $pet->id, '10008', 'got the proper pet id';
+is $pet->name, 'perl test', 'got the proper pet name';
+is $pet->category->id, '22', 'got the proper category id';
+is $pet->category->name, 'perl', 'got the proper category name';
+is $pet->tags->[0]->name, 'just kidding', 'got the proper tag name';
+is $pet->tags->[0]->id, '11', 'got the proper tag id';
+
+
+my $add_pet = $api->add_pet(body => $pet);
+my $get_pet = $api->get_pet_by_id(pet_id => $pet_id);
+
+is $get_pet->id, '10008', 'stored and retrieved: got the proper pet id';
+is $get_pet->name, 'perl test', 'stored and retrieved: got the proper pet name';
+is $get_pet->category->id, '22', 'stored and retrieved: got the proper category id';
+is $get_pet->category->name, 'perl', 'stored and retrieved: got the proper category name';
+is $get_pet->tags->[0]->name, 'just kidding', 'stored and retrieved: got the proper tag name';
+is $get_pet->tags->[0]->id, '11', 'stored and retrieved: got the proper tag id';
+
+# documentation tests
+
+# API method docs
+is_deeply( [sort keys %{$api->pet_api->method_documentation}],
+ [ 'add_pet', 'delete_pet', 'find_pets_by_status', 'find_pets_by_tags', 'get_pet_by_id', 'update_pet', 'update_pet_with_form', 'upload_file'],
+ "Pet API method_documentation has the correct keys");
+is $api->pet_api->method_documentation->{get_pet_by_id}->{params}->{pet_id}->{description},
+ 'ID of pet that needs to be fetched', 'get_pet_by_id parameter pet_id description is correct';
+is $api->pet_api->method_documentation->{get_pet_by_id}->{params}->{pet_id}->{required},
+ 1, 'get_pet_by_id parameter pet_id is required';
+is $api->pet_api->method_documentation->{get_pet_by_id}->{params}->{pet_id}->{data_type},
+ 'int', 'get_pet_by_id parameter pet_id is an int';
+is $api->pet_api->method_documentation->{get_pet_by_id}->{returns},
+ 'Pet', 'get_pet_by_id returns a Pet';
+is $api->pet_api->method_documentation->{get_pet_by_id}->{summary},
+ 'Find pet by ID', 'get_pet_by_id summary is correct';
+
+# object class docs
+my $pet_class_doco = { 'description' => '', required => [], class => 'Pet' };
+is_deeply($get_pet->class_documentation, $pet_class_doco, 'Pet object class_documentation is available');
+is $get_pet->class_documentation->{description}, '', 'Pet object class_documentation is correct'; # right now it's blank
+is $get_pet->class_documentation->{class}, 'Pet', 'Pet object class_documentation returns correct class name';
+
+# object method docs
+is $get_pet->method_documentation->{status}->{description}, 'pet status in the store', 'Pet object method_documentation for status() - description is correct';
+is $get_pet->method_documentation->{status}->{format}, '', 'Pet object method_documentation for status() - format is correct';
+is $get_pet->method_documentation->{status}->{base_name}, 'status', 'Pet object method_documentation for status() - base_name is correct';
+is $get_pet->method_documentation->{status}->{datatype}, 'string', 'Pet object method_documentation for status() - datatype is correct';
+
+
+
+# / documentation tests
+
+my $tokens = {
+ username => 'UserName',
+ password => 'PassWord',
+ access_token => 'OAuth_token',
+
+ someKey => { token => 'some_key_token',
+ prefix => 'some_key_prefix',
+ in => 'query',
+ },
+
+ anotherKey => { token => 'another_key_token',
+ },
+ };
+
+$api->_cfg->accept_tokens({%$tokens}); # pass a copy
+no warnings 'once';
+is $WWW::SwaggerClient::Configuration::username, 'UserName', 'accept_tokens() correctly set the username';
+is $WWW::SwaggerClient::Configuration::password, 'PassWord', 'accept_tokens() correctly set the password';
+is $WWW::SwaggerClient::Configuration::access_token, 'OAuth_token', 'accept_tokens() correctly set the oauth';
+
+my $api_key_href = {
+ 'anotherKey' => 'another_key_token',
+ 'someKey' => 'some_key_token'
+ };
+cmp_deeply( $WWW::SwaggerClient::Configuration::api_key, $api_key_href, 'accept_tokens() correctly set api_key' );
+
+my $api_key_prefix_href = {
+ 'someKey' => 'some_key_prefix'
+ };
+cmp_deeply( $WWW::SwaggerClient::Configuration::api_key_prefix, $api_key_prefix_href, 'accept_tokens() correctly set api_key_prefix' );
+
+my $api_key_in = {
+ 'someKey' => 'query',
+ 'anotherKey' => 'head'
+ };
+cmp_deeply( $WWW::SwaggerClient::Configuration::api_key_in, $api_key_in, 'accept_tokens() correctly set api_key_in' );
+
+use warnings 'once';
+
+my $cleared_tokens_cmp = {
+ 'anotherKey' => {
+ 'in' => 'head',
+ 'token' => 'another_key_token',
+ 'prefix' => undef
+ },
+ 'access_token' => 'OAuth_token',
+ 'someKey' => {
+ 'token' => 'some_key_token',
+ 'in' => 'query',
+ 'prefix' => 'some_key_prefix'
+ },
+ 'username' => 'UserName',
+ 'password' => 'PassWord'
+ };
+cmp_deeply( $api->_cfg->clear_tokens, $cleared_tokens_cmp, 'clear_tokens() returns the correct data structure' );
+
+my $bad_token = { bad_token_name => 'bad token value' }; # value should should be hashref
+dies_ok { $api->_cfg->accept_tokens($bad_token) } "bad token causes exception";
+
+
+} # / SKIP
+