AI-Image

 view release on metacpan or  search on metacpan

Changes  view on Meta::CPAN

Revision history for AI-Image

0.01    6th March 2024
         First version, released on an unsuspecting world.

MANIFEST  view on Meta::CPAN

Changes
lib/AI/Image.pm
Makefile.PL
MANIFEST			This list of files
README
t/00-load.t
t/01-openai.t
t/manifest.t
t/pod-coverage.t
t/pod.t
t/version.t

META.yml                                 Module YAML meta-data (added by MakeMaker)
META.json                                Module JSON meta-data (added by MakeMaker)

META.json  view on Meta::CPAN

{
   "abstract" : "Generate images using OpenAI's DALL-E",
   "author" : [
      "Ian Boddison <bod@cpan.org>"
   ],
   "dynamic_config" : 1,
   "generated_by" : "ExtUtils::MakeMaker version 7.58, CPAN::Meta::Converter version 2.150010",
   "license" : [
      "perl_5"
   ],
   "meta-spec" : {
      "url" : "http://search.cpan.org/perldoc?CPAN::Meta::Spec",
      "version" : 2
   },
   "name" : "AI-Image",
   "no_index" : {
      "directory" : [
         "t",
         "inc"
      ]
   },
   "prereqs" : {
      "build" : {
         "requires" : {
            "ExtUtils::MakeMaker" : "0"
         }
      },
      "configure" : {
         "requires" : {
            "ExtUtils::MakeMaker" : "0"
         }
      },
      "runtime" : {
         "requires" : {
            "Carp" : "1.50",
            "HTTP::Tiny" : "0.014",
            "JSON::PP" : "2.00",
            "perl" : "5.010"
         }
      },
      "test" : {
         "requires" : {
            "Test::More" : "0"
         }
      }
   },
   "release_status" : "stable",
   "version" : "0.1",
   "x_serialization_backend" : "JSON::PP version 4.06"
}

META.yml  view on Meta::CPAN

---
abstract: "Generate images using OpenAI's DALL-E"
author:
  - 'Ian Boddison <bod@cpan.org>'
build_requires:
  ExtUtils::MakeMaker: '0'
  Test::More: '0'
configure_requires:
  ExtUtils::MakeMaker: '0'
dynamic_config: 1
generated_by: 'ExtUtils::MakeMaker version 7.58, CPAN::Meta::Converter version 2.150010'
license: perl
meta-spec:
  url: http://module-build.sourceforge.net/META-spec-v1.4.html
  version: '1.4'
name: AI-Image
no_index:
  directory:
    - t
    - inc
requires:
  Carp: '1.50'
  HTTP::Tiny: '0.014'
  JSON::PP: '2.00'
  perl: '5.010'
version: '0.1'
x_serialization_backend: 'CPAN::Meta::YAML version 0.018'

Makefile.PL  view on Meta::CPAN

use 5.010;
use strict;
use warnings;
use ExtUtils::MakeMaker;

my %WriteMakefileArgs = (
    NAME             => 'AI::Image',
    AUTHOR           => q{Ian Boddison <bod@cpan.org>},
    VERSION_FROM     => 'lib/AI/Image.pm',
    ABSTRACT_FROM    => 'lib/AI/Image.pm',
    LICENSE          => 'Perl',
    MIN_PERL_VERSION => '5.010',
    CONFIGURE_REQUIRES => {
        'ExtUtils::MakeMaker' => '0',
    },
    TEST_REQUIRES => {
        'Test::More' => '0',
    },
    PREREQ_PM => {
        'Carp'           => '1.50',
        'JSON::PP'       => '2.00',
        'HTTP::Tiny'     => '0.014',
    },
    dist  => { COMPRESS => q{perl -MIO::Compress::Gzip=gzip,:constants -e"my $$in = $$ARGV[0]; gzip($$in => qq($$in.gz), q(Level) => Z_BEST_COMPRESSION, q(BinModeIn) => 1) or die q(gzip failed); unlink $$in;"}, SUFFIX => 'gz', },
    clean => { FILES => 'AI-Image-*' },
);

# Compatibility with old versions of ExtUtils::MakeMaker
unless (eval { ExtUtils::MakeMaker->VERSION('6.64'); 1 }) {
    my $test_requires = delete $WriteMakefileArgs{TEST_REQUIRES} || {};
    @{$WriteMakefileArgs{PREREQ_PM}}{keys %$test_requires} = values %$test_requires;
}

unless (eval { ExtUtils::MakeMaker->VERSION('6.55_03'); 1 }) {
    my $build_requires = delete $WriteMakefileArgs{BUILD_REQUIRES} || {};
    @{$WriteMakefileArgs{PREREQ_PM}}{keys %$build_requires} = values %$build_requires;
}

delete $WriteMakefileArgs{CONFIGURE_REQUIRES}
    unless eval { ExtUtils::MakeMaker->VERSION('6.52'); 1 };
delete $WriteMakefileArgs{MIN_PERL_VERSION}
    unless eval { ExtUtils::MakeMaker->VERSION('6.48'); 1 };
delete $WriteMakefileArgs{LICENSE}
    unless eval { ExtUtils::MakeMaker->VERSION('6.31'); 1 };

WriteMakefile(%WriteMakefileArgs);

README  view on Meta::CPAN

AI-Image

The README is used to introduce the module and provide instructions on
how to install the module, any machine dependencies it may have (for
example C compilers and installed libraries) and any other information
that should be provided before the module is installed.

A README file is required for CPAN modules since CPAN extracts the README
file from a module distribution so that people browsing the archive
can use it to get an idea of the module's uses. It is usually a good idea
to provide version information here so that people can decide whether
fixes for the module are worth downloading.


INSTALLATION

To install this module, run the following commands:

	perl Makefile.PL
	make
	make test
	make install

SUPPORT AND DOCUMENTATION

After installing, you can find documentation for this module with the
perldoc command.

    perldoc AI::Image

You can also look for information at:

    RT, CPAN's request tracker (report bugs here)
        https://rt.cpan.org/NoAuth/Bugs.html?Dist=AI-Image

    CPAN Ratings
        https://cpanratings.perl.org/d/AI-Image

    Search CPAN
        https://metacpan.org/release/AI-Image


LICENSE AND COPYRIGHT

This software is Copyright (c) 2024 by Ian Boddison.

This program is released under the following license:

  Perl

lib/AI/Image.pm  view on Meta::CPAN

package AI::Image;

use strict;
use warnings;

use strict;
use warnings;

use Carp;
use HTTP::Tiny;
use JSON::PP;

our $VERSION = '0.1';
$VERSION = eval $VERSION;

my $http = HTTP::Tiny->new;

# Create Image object
sub new {
    my $class = shift;
    my %attr  = @_;

    $attr{'error'}      = '';

    $attr{'api'}        = 'OpenAI' unless $attr{'api'};
    $attr{'error'}      = 'Invalid API' unless $attr{'api'} eq 'OpenAI';
    $attr{'error'}      = 'API Key missing' unless $attr{'key'};

    $attr{'model'}      = 'dall-e-2' unless $attr{'model'};
    $attr{'size'}       = '512x512'  unless $attr{'size'};

    return bless \%attr, $class;
}

# Define endpoints for APIs
my %url    = (
    'OpenAI' => 'https://api.openai.com/v1/images/generations',
);

# Define HTTP Headers for APIs
my %header = (
    'OpenAI' => &_get_header_openai,
);

# Returns true if last operation was success
sub success {
    my $self = shift;
    return !$self->{'error'};
}

# Returns error if last operation failed
sub error {
    my $self = shift;
    return $self->{'error'};
}

# Header for calling OpenAI
sub _get_header_openai {
    my $self = shift;
    $self->{'key'} = '' unless defined $self->{'key'};
    return {
         'Authorization' => 'Bearer ' . $self->{'key'},
         'Content-type'  => 'application/json'
     };
 }

# Get URL from image prompt
sub image {
    my ($self, $prompt) = @_;

    my $response = $http->post($url{$self->{'api'}}, {
         'headers' => {
             'Authorization' => 'Bearer ' . $self->{'key'},
             'Content-type'  => 'application/json'
         },
         content => encode_json {
             model          => $self->{'model'},
             size           => $self->{'size'},
             prompt         => $prompt,
         }
     });
     if ($response->{'content'} =~ 'invalid_api_key') {
         croak 'Incorrect API Key - check your API Key is correct';
     }
     
     if ($self->{'debug'} and !$response->{'success'}) {
         croak $response if $self->{'debug'} eq 'verbose';
         croak $response->{'content'};
     }

     my $reply = decode_json($response->{'content'});

     return $reply->{'data'}[0]->{'url'};
}

__END__

=head1 NAME

AI::Image - Generate images using OpenAI's DALL-E

=head1 VERSION

Version 0.1

=head1 SYNOPSIS

    use AI::Image;

    my $ai = AI::Image->new(
        'key'   => 'sk-......',
    );
    
    my $image_url = $ai->image("A photorealistic image of a cat wearing a top hat and monocle.");

    print $image_url;

=head1 DESCRIPTION

This module provides a simple interface to generate images using OpenAI's DALL-E API.

=head1 API KEYS

A free OpenAI API can be obtained from L<https://platform.openai.com/account/api-keys>

=head1 MODELS

Although the API Key is free, each use incurs a cost.  This is dependent on the
model chosen and the size.  The 'dall-e-3' model produces better images but at a
higher cost.  Likewise, bigger images cost more.
The default model C<dall-e-2> with the default size of C<512x512> produces resonable
results at a low cost and is a good place to start using this module.

See also L<https://platform.openai.com/docs/models/overview>

=head1 METHODS

=head2 new

  my $ai = AI::Image->new(%params);

Creates a new AI::Image object.

=head3 Parameters

=over 4

=item key

C<required> Your OpenAI API key.

=item api

The API to use (currently only 'OpenAI' is supported).

=item model

The language model to use (default: 'dall-e-2').

See L<https://platform.openai.com/docs/models/overview>

=item size

The size for the generated image (default: '512x512').

=item debug

Used for testing.  If set to any true value, the image method
will return details of the error encountered instead of C<undef>

=back

=head2 image

  my $url = $ai->image($prompt);

Generates an image based on the provided prompt and returns the URL of the generated image.  The URL is valid for 1 hour.

=head3 Parameters

=over 4

=item prompt

The textual description of the desired image.

=back

=head2 success

  my $success = $ai->success();

Returns true if the last operation was successful.

=head2 error

  my $error = $ai->error();

Returns the error message if the last operation failed.

=head1 EXAMPLE

It is common that the generated image will want to be saved as a file.  This can be easily acheived
using the C<getstore> method of L<LWP::Simple>.

    use strict;
    use warnings;
    
    use LWP::Simple;
    use AI::Image;
    
    my $ai = AI::Image->new(
        'key'   => 'sk-......',
    );
    
    my $image_url = $ai->image("A dog reading a newspaper");
    
    getstore( $image_url, 'my_ai_image.png' );


=head1 SEE ALSO

L<https://openai.com> - OpenAI official website

=head1 AUTHOR

Ian Boddison <ian at boddison.com>

=head1 BUGS

Please report any bugs or feature requests to C<bug-ai-image at rt.cpan.org>, or through
the web interface at L<https://rt.cpan.org/NoAuth/ReportBug.html?Queue=bug-ai-image>.  I will be notified, and then you'll
automatically be notified of progress on your bug as I make changes.

=head1 SUPPORT

You can find documentation for this module with the perldoc command.

    perldoc AI::Image

You can also look for information at:

=over 4

=item * RT: CPAN's request tracker (report bugs here)

L<https://rt.cpan.org/NoAuth/Bugs.html?Dist=AI-Image>

=item * Search CPAN

L<https://metacpan.org/release/AI::Image>

=back

=head1 COPYRIGHT AND LICENSE

Copyright (C) 2024 by Ian Boddison

This library is free software; you can redistribute it and/or modify
it under the same terms as Perl itself.

=cut

t/00-load.t  view on Meta::CPAN

#!perl
use 5.006;
use strict;
use warnings;
use Test::More;

plan tests => 1;

BEGIN {
    use_ok( 'AI::Image' ) || print "Bail out!\n";
}

diag( "Testing AI::Image $AI::Image::VERSION, Perl $], $^X" );

t/01-openai.t  view on Meta::CPAN

#!perl
use 5.006;
use strict;
use warnings;
use Test::More;

use AI::Image;

my $image_fai11 = AI::Image->new();

ok( $image_fai11->isa( 'AI::Image' ),  'Instantiation' );
ok( !$image_fai11->success, 'Key Error during object creation' );

my $image_fail2 = AI::Image->new(
    'key'   => '0123456789',
    'api'   => 'Not Allowed',
);

ok( $image_fail2->isa( 'AI::Image' ),  'Instantiation' );
ok( !$image_fail2->success, 'API Error during object creation' );

my $image_pass = AI::Image->new(
    'key'   => '0123456789',
    'api'   => 'OpenAI',
);

ok( $image_pass->isa( 'AI::Image' ), 'Instantiation' );
ok( $image_pass->success, 'Successful object creation' );

done_testing(6);


    

t/manifest.t  view on Meta::CPAN

#!perl
use 5.006;
use strict;
use warnings;
use Test::More;

unless ( $ENV{RELEASE_TESTING} ) {
    plan( skip_all => "Author tests not required for installation" );
}

my $min_tcm = 0.9;
eval "use Test::CheckManifest $min_tcm";
plan skip_all => "Test::CheckManifest $min_tcm required" if $@;

ok_manifest();

t/pod-coverage.t  view on Meta::CPAN

#!perl
use 5.006;
use strict;
use warnings;
use Test::More;

unless ( $ENV{RELEASE_TESTING} ) {
    plan( skip_all => "Author tests not required for installation" );
}

# Ensure a recent version of Test::Pod::Coverage
my $min_tpc = 1.08;
eval "use Test::Pod::Coverage $min_tpc";
plan skip_all => "Test::Pod::Coverage $min_tpc required for testing POD coverage"
    if $@;

# Test::Pod::Coverage doesn't require a minimum Pod::Coverage version,
# but older versions don't recognize some common documentation styles
my $min_pc = 0.18;
eval "use Pod::Coverage $min_pc";
plan skip_all => "Pod::Coverage $min_pc required for testing POD coverage"
    if $@;

all_pod_coverage_ok();

t/pod.t  view on Meta::CPAN

#!perl
use 5.006;
use strict;
use warnings;
use Test::More;

unless ( $ENV{RELEASE_TESTING} ) {
    plan( skip_all => "Author tests not required for installation" );
}

# Ensure a recent version of Test::Pod
my $min_tp = 1.22;
eval "use Test::Pod $min_tp";
plan skip_all => "Test::Pod $min_tp required for testing POD" if $@;

all_pod_files_ok();

t/version.t  view on Meta::CPAN

#!/usr/bin/perl
use warnings;
use strict;
use Test::More;

use AI::Image;

unless ( $ENV{RELEASE_TESTING} ) {
    plan( skip_all => "Author tests not required for installation" );
}

my $code_version = $AI::Image::VERSION;
ok($code_version, 'version set');

ok(open(my $source, '<', $INC{'AI/Image.pm'}), 'open the source');

my $in_version;
while (<$source>) {
    if (/^=head1 VERSION/) {
        $in_version = 1;
    } elsif (/^=head1/) {
        undef $in_version;
    }
    if ($in_version && /^Version ([0-9.]+)/) {
        is($code_version, $1, 'pod version');
    }
}

done_testing();

 view all matches for this distribution
 view release on metacpan -  search on metacpan

( run in 0.961 second using v1.00-cache-2.02-grep-82fe00e-cpan-cec75d87357c )