Giter Site home page Giter Site logo

pksunkara / alpaca Goto Github PK

View Code? Open in Web Editor NEW
2.5K 72.0 89.0 370 KB

Given a web API, Generate client libraries in node, php, python, ruby

License: Mozilla Public License 2.0

Makefile 1.41% Go 24.49% JavaScript 17.17% PHP 19.63% Python 19.06% Ruby 18.25%
alpaca api client-library api-client apis golang go

alpaca's Introduction

alpaca Build Status Gitter chat

Api Libraries Powered And Created by Alpaca


Tired of maintaining API libraries in different languages for your website API? This is for you

You have an API for your website but no API libraries for whatever reason? This is for you

You are planning to build an API for your website and develop API libraries? This is for you


You define your API according to the format given below, alpaca builds the API libraries along with their documentation. All you have to do is publishing them to their respective package managers.

Join us at gitter if you need any help.

Installation

You can download the binaries (v0.2.1)

Or by using deb packages (v0.2.1)

Or by using golang (v1.2)

# Clone the project into your golang workspace
$ git clone git://github.com/pksunkara/alpaca
$ cd alpaca

# Install program
$ make && make install

Examples

You can find some api definitions in the examples directory. The api libraries generated are at https://github.com/alpaca-api

Completed api definitions are buffer.

Usage

$ alpaca </path/to/dir>

The path here should be a directory with api.json, pkg.json, doc.json

Usage:
  alpaca [options] <dir>

Application Options:
  -v, --version    Show version information

Language Options:
      --no-php     Do not write php library
      --no-python  Do not write python library
      --no-ruby    Do not write ruby library
      --no-node    Do not write node library

Help Options:
  -h, --help       Show this help message

Please remove the comments when actually using these json files

pkg.json

All the following fields are required unless mentioned.

{
  "name": "Example", // Name of the api (also used as class name for the library)
  "package": "example-alpaca", // Name of the package
  "version": "0.1.0", // Version of the package
  "url": "https://exampleapp.com", // URL of the api
  "keywords": ["alpaca", "exampleapp", "api"], // Keywords for the package
  "official": false, // Are the api libraries official?
  "author": {
    "name": "Pavan Kumar Sunkara", // Name of the package author
    "email": "[email protected]", // Email of the package author
    "url": "http://github.com/pksunkara" // URL of the package author
  },
  "git": { // Used in the package definition
    "site": "github.com", // Name of the git website
    "user": "alpaca-api", // Username of the git website
    "name": "buffer" // Namespace of the git repositories
  },
  "license": "MIT", // License of the package
  "php": { // Required only if creating php api lib
    "vendor": "pksunkara" // Packagist vendor name for the package
  },
  "python": { // Required only if creating python api lib
    "license": "MIT License" // Classifier of the license used for the module
  }
}

api.json

All the following fields are required unless mentioned.

{
  "base": "https://exampleapp.com", // Base URL of the api
  "base_as_arg": true, // Force Base URL to be an argument in generated clients [optional] (default: false)
  "version": "v1", // Default version for the api (https://api.example.com{/version}/users) [optional]
  "no_verify_ssl": true, // Do not verify SSL cert [optional] (default: false)
  "authorization": { // Authorization strategies
    "need_auth": true, // Authentication is compulsory [optional] (default: false)
    "basic" : true, // Basic authentication [optional] (default: false)
    "header": true, // Token in authorization header [optional] (default: false)
    "header_prefix": "oompaloompa", // The first word in header if using token auth header [optional] (default: token)
    "oauth" : true // OAUTH authorization [optional] (default: false)
  },
  "request": { // Settings for requests to the api
    "formats": { // Format of the request body
      "default": "form", // Default format for the request body [optional] (default: raw)
      "form": true, // Support form-url-encoded? [optional] (default: false)
      "json": true // Support json? [optional] (default: false)
    }
  },
  "response": { // Settings for responses from the api
    "suffix": true, // Should the urls be suffixed with response format? [optional] (default: false)
    "formats": { // Format of the response body
      "default": "json", // Default response format. Used when 'suffix' is 'true'
      "html": true, // Support html? [optional] (default: false)
      "json": true // Support json? [optional] (default: false)
    }
  },
  "error": { // Required if response format is 'json'
    "message": "error" // The field to be used from the response body for error message
  },
  "class": { // The classes for the api
    "users": { // Name of a class of the api
      "args": ["login"], // Arguments required for the api class [optional]
      "profile": { // Name of a method of the api
        "path": "/users/:login/:type", // URL of the api method
        "method": "post", // HTTP method of the api method [optional] (default: get)
        "params": [ // Parameters for the api method [optional]
          {
            "name": "type", // Name of the parameter
            "required": true, // The parameter will become an argument of api method [optional] (default: false)
            "url_use": true // This parameter is only used to build url [optional] (default: false)
          },
          {
            "name": "bio",
            "required": true
          }
        ]
      }
    }
  }
}

doc.json

The following is filled according to the entries in api.json

{
  "users": { // Name of a class of the api
    "title": "Users", // Title of the api class
    "desc": "Returns user api instance", // Description of the api class
    "args": { // Arguments of the api class
      "login": { // Name of the argument
        "desc": "Username of the user", // Description of the argument
        "value": "pksunkara" // Value of the argument in docs
      }
    },
    "profile": { // Name of a method of the api
      "title": "Edit profile", // Title of the api method
      "desc": "Edit the user's profile", // Description of the api method
      "params": { // Parameter of the api class
        "bio": { // Name of the parameter
          "desc": "Short bio in profile", // Description of the parameter
          "value": "I am awesome!" // Value of the parameter in docs
        },
        "type": {
          "desc": "Circle of the profile",
          "value": "friends"
        }
      }
    }
  }
}

Request formats

Supported request formats are raw, form, json. The format raw is always true.

This means, the body set in the options when calling an API method will be able to be encoded according to the respective request_type

If set to raw, body is not modified at all

Response formats

Supported response formats are html, json.

Authorization strategies

Supported are basic, header, oauth

Language Versions

Supported programming language versions are:

Language V E R S I O N
node 0.8 0.9 0.10 0.11 0.12
php 5.4 5.5
python 2.6 2.7 3.2 3.3
ruby 1.8.7 1.9.1 1.9.2 1.9.3 2.0.0 2.1.0 2.1.1

Package Managers

Language Package Manager
node https://npmjs.org
php https://packagist.org
python https://pypi.python.org
ruby https://rubygems.org

Testing

Check here to learn about testing.

Contributors

Here is a list of Contributors

I accept pull requests and guarantee a reply back within a day

TODO

You get internet points for pull requesting the following features.

Responses
Requests
  • HTTP Method Overloading
  • What about file uploads?
API
  • Check returned status code
  • Special case for 204:true and 404:false
Libraries
  • Pagination support
  • Classes inside classes (so on..)
  • Validations for params/body in api methods
  • Allow customization of errors
  • Tests for libraries (lots and lots of tests)
Readme
Comments
  • The descriptions should be wrapped
  • Align @param descriptions
Formats
Languages

Support Projects

Alternatively, you can write your own converter from alpaca.json to the following

  • Convert into API Blueprint
  • Convert into Swagger

License

MIT/X11

Bug Reports

Report here. Guaranteed reply within a day.

Contact

Pavan Kumar Sunkara ([email protected])

Follow me on github, twitter

alpaca's People

Contributors

avelis avatar haraldnordgren avatar index0h avatar jnovinger avatar macropin avatar matrixik avatar mikecarroll avatar mikkvais avatar pksunkara avatar rajatkhanduja avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

alpaca's Issues

Buttons on Designer are buggy

Big bug on the designer ( even in the officialdemo online ), Sheama and Options buttons on "Designer" tab are returning the following error :
View compilation failed - cannot find parent view: VIEW_BOOTSTRAP_EDIT_LIST for view: VIEW_alpaca....

Add flexibility to Authorization header configuration

For the generated PHP code, looking at AuthHandler.php line 58, the header generated is Authorization: token %s. This is not compatible with all API servers. In my case, I need to change token to Token (in other words, capitalize the word 'token') for the API calls to work.

Propose one of two changes:

  1. If the standard is to use the capitalized version of the word 'Token', simply change the generated code accordingly.
    Or:
  2. Add the ability to customize the word 'token' via the api.json configuration file.

Presumably the change would be applicable generally, i.e. to all generated client code in all languages (not just PHP).

Required predefined body parametres

Hi.
In case when api has many simple methods, which differ only one parameter, it could be useful to create multiple methods with that predefined parameter.

For example: DigitalOcean V2 API:
Droplet has many actions like: reboot, power on, power off. They differ only in parameter "type": "reboot", "power_on", "power_off".

Now I could to create method run_action($droplet_id, $type), but it's more easy to use simple methods like: reboot($id), power_on($id), power_off($id)

Best implementation (imho) could be something like this:

public function reboot($id, array $options = array())
{
    $body = (isset($options['body']) ? $options['body'] : array());
    $body['type'] = 'reboot';

    $response = $this->client->post('/droplets/'.rawurlencode($id).'/actions', $body, $options);

    return $response;
}

Regards

Support custom error/status code in response body

Some APIs return status of response in body. And some badly designed APIs return always HTTP 200 and real status code in body.

bit.ly: http://dev.bitly.com/formats.html

HTTP Response Status Code is 200 on all valid response in json and xml formats. In json and xml responses, the status_code and status_txt values indicate whether a request is well formed and valid.

  • json { "status_code": 200, "status_txt": "OK", "data" : ... }
  • json { "status_code": 403, "status_txt": "RATE_LIMIT_EXCEEDED", "data" : null }

ArangoDB: https://www.arangodb.org/manuals/current/HttpDatabase.html
Return codes

  • HTTP 201 - is returned if the database was created successfully.
  • HTTP 400 - is returned if the request parameters are invalid or if a database with the specified name already exists.
  • HTTP 403 - is returned if the request was not executed in the _system database.
  • HTTP 409 - is returned if a database with the specified name already exists.

{ "result" : true, "error" : false, "code" : 201 }

Would be nice if we could add code in body names to api.json.

Not building on windows

Hello,

I would like to play with templates and I need to build alpaca on Windows but Makefile is a little cryptic to me.

Can you provide some simple step by step way of building alpaca on Windows (without compiling templates into it)?
Or maybe can you provide alpaca binary without templates compiled in?

Best regards,
Dobrosław Żybort

Error running the examples

I was running the examples. All the examples except buffer give errors

invalid character '"' after object key:value pair
OR
invalid character '}' looking for beginning of object key string.

Error executing "php/readme.md"

I'm sure I'm missing something. I read through the documentation and included the fields that are required. I'm getting the following error:

template: php/readme.md:171:20: executing "php/readme.md" at <index $data.Doc $cla...>: error calling index: index of nil pointer

Problem with definition of parameters vs documentation

Hi,

First, great project, great idea! :)

I do have an issue with the ease of keeping documentation text in a separate doc.js file, which means there is the need to stay synchronized with the "class" portion of the api.js and the order of params defined in there.

Currently, params are defined as an array. This means it's not possible to add code-relevant information to each param (eg, "type" for typed/hinted languages such as PHP), but also means that if the order of parameters is changed, the documentation becomes incorrect.

I would suggest changing api.js so that instead of this:

    "create_update": {
            ...
            "params": ["text", "profile_ids"]
     }

You'd instead write the params field as an object, and could also provide info immediately in there. I also suggest adding a type field, which if used can generate type hints for the method signatures. So, in the api.js file you'd write:

    "create_update": {
            ...
            "params": {
                "text": {
                     "type": "string",  // optional
                     "desc": "This is the status update text.",  // optional
                     "value": "This is an example update"  // optional
                 },
                 "profile_ids": {}, // don't define anything for this field, will be done only in doc.js
            }
    }

The doc.js file would then become:

    "create_update": {
            ...
            "params": {
                "text": {
                     "type": "string",
                     "desc": "Here you'd write the text for the status update.",
                     "value": "This is my status!"
                 },
                 "profile_ids": {
                     "type": "array",
                     "desc": "An array of profile id's that the status update should be sent to. Invalid profile_id's will be silently ignored.",
                     "value": ["4eb854340acb04e870000010", "4eb9276e0acb04bb81000067"]
                 },
            }
    }

With this change you no longer need to worry about the order of parameters. This also means that in the future, you could allow multi-language documentation to be generated by having multiple files (eg, doc_EN.js, doc_DE.js), with different people doing the writing and the programmers only caring about api.js.

If you'd like to keep these formats backwards-compatible, you can check whether params is an array or a hash (object), but personally, I'd suggest breaking backwards compatibility. It's a young project, it's too early to be burdened with backwards compatibility, and it's an easy change for people to do. :)

Panic on running Alpaca on OSX 10.9 64-Bit

panic: interface conversion: interface is nil, not []interface {}

goroutine 1 [running]:
runtime.panic(0x1792a0, 0x210499380)
    /usr/local/lib/gvm/gos/go1.2/src/pkg/runtime/panic.c:266 +0xb6
github.com/pksunkara/alpaca/alpaca.ArrayInterfaceToString(0x0, 0x0, 0x1b5a50, 0x8, 0x201d40)
    /usr/local/lib/gvm/pkgsets/go1.2/global/src/github.com/pksunkara/alpaca/alpaca/utils.go:21 +0x43
github.com/pksunkara/alpaca/alpaca.ModifyData(0x21045e600)
    /usr/local/lib/gvm/pkgsets/go1.2/global/src/github.com/pksunkara/alpaca/alpaca/alpaca.go:54 +0x63
github.com/pksunkara/alpaca/alpaca.WriteLibraries(0x7fff5fbff817, 0x2, 0x210454841)
    /usr/local/lib/gvm/pkgsets/go1.2/global/src/github.com/pksunkara/alpaca/alpaca/alpaca.go:34 +0x7a
main.main()
    /usr/local/lib/gvm/pkgsets/go1.2/global/src/github.com/pksunkara/alpaca/main.go:48 +0x1ec

Installed the Darwin amd64 version of the packaged application

PHP namespace fatal error?

Sorry if this is not a bug, as this is my first exposure to namespaces (in PHP, anyway). The issue can be re-created using the generated Buffer PHP client code. To do so, please edit Client.php and instantiate the class as follows:

$x = new Client();

Then, run from command line with: php Client.php. This generates an error:

PHP Fatal error:  Class 'Buffer\HttpClient\HttpClient' not found ...

This issue was discovered when generating a new API client, which resulted in a similar error, the example is simply to help in reproducing (what appears to be) an issue.

PHP version used: 5.3.10.

Will keep reading up on namespaces and attempt to isolate the issue (or figure out the error on my end). Thanks.

Format: YAML

Reading from alpaca.yaml instead of alpaca.json

Improve reporting of invalid API defition in JSON file

When something is wrong in doc.json

  • missing class def
  • missing param

I got some general error like:

template: php/readme.md:188:20: executing "php/readme.md" at <index $data.Doc $cla...>: error calling index: index of nil pointer

or

template: php/readme.md:170:6: executing "php/readme.md" at <index $data.Doc . "t...>: error calling index: index of nil pointer

Should we improve this error message? Like missing definition of class, or missing param def of method...

Validation

Fantastic project, firstly.

I think it would benefit greatly from basic validations on parameters. For example, if you require an integer cost to be submitted in the request, the following would be added to the api.json

"purchase": {
    "args": ["id"],
    "list": {
        "path": "/purchases/"
    },
    "update": {
        "path": "/purchases/:id/",
        "method": "post",
        "params": [
            {
                "name": "cost",
                "validation": "integer",
                "required": true
            }
        ]
    }
}

This cuts down on requests that will automatically be rejected by the API anyway, and most libraries include them.

Receiving Error

"template: php/readme.md:159:16: executing "php/readme.md" at <index $data.Doc $cla...>: error calling index: index of nil pointer"

Error PHP url_use parameter option

Hi there.

There is an error with generated result of method with url_use = true in php result.

Next api.json part

// ...
    "class": {
        "domain": {
            "retrieve": {
                "path": "/domains/:name",
                "method": "get",
                "params": [
                    {
                        "name": "name",
                        "required": true,
                        "url_use": true
                    }
                ]
            }
        }
// ...

generates

/**
 * domain retrieve desc
 *
 * '/domains/:name' GET
 *
 * @param $name domain retrieve name desc
 */
public function retrieve($name, array $options = array())
{
    $body = (isset($options['query']) ? $options['query'] : array());

    $response = $this->client->get('/domains/'.rawurlencode(name).'', $body, $options);

    return $response;
}

The problem is rawurlencode(name), it must be rawurlencode($name)

Regards

Does this generate documentation?

I'm confused -- does this generate documentation with code examples, or does this generate source files that are examples for end users that can be compiled? I don't see any meanful examples of the end product.

Force custom URL for API

I would like to create libraries for database ArangoDB (and at future for Wordpress) but it is self hosted and don't have one, static API URL.

Could you add method to generated libraries, so that programmers are forced to initialize API client with custom URL?
Like:

class Client(object):
    def __init__(self, base_url, auth={}, options={}):
        self.http_client = HttpClient(base_url, auth, options)

A mechanism to deploy to a package registry

Speaking of packagist and composer,
I found that it's easier to work on same directory with 2 branches:

  • master: for php source itself which is generated from alpace
  • alpace: hold JSON configuration

I then use a custom makefile to generate the API, copy to a temporary folder, the checkout to master branch, copy file back and commit.

I experiment with it for a bit https://github.com/kureikain/bandwidth-php (check out master and alpaca branch)

Though I feel it's tricky. Do you have any idea/method so I can work on same directory but maintain the API JSON file and the generate file at same time but keep them separate so when I published to registry, the API JSON file won't leak into PHP source.

Default headers for clients

My API requires custom headers, for a use case similar to this scenario:

Where I've seen custom headers com up is in a system to system request operating on behalf of a user. The proxy system will validate the user and add "X-User: userid" to the headers and use the system credentials to hit the endpoint. The receiving system validates that the system credentials are authorized to act on behalf of the user, then validate that the user is authorized to perform the action. http://stackoverflow.com/a/9169270/149060

I was concerned that I didn't see support for them in the todo list.

Alpaca runs sucessfully, but I don't see the created files

I installed the .deb package on Ubuntu successfully, and copied over the buffer example folder. When I run alpaca on the folder, i don't get any error message, but the API wrappers don't appear in the directory with the original Alpaca files or anywhere else that I can see.

Format: WADL

Although not all RESTful web services generate WADL files it would be nice to have a feature developed to generate client libs based on this document format.

A number of REST frameworks like Jersey support generation of WADL files.

Generate functions in same order

Always generate methods in same (e.g. alphabetical) order.

Actual behaviour:
First time:

class Profile(object):

    def __init__(self, id, client):
        ...
    def reorder(self, order, options={}):
        ...
        return response

    def shuffle(self, options={}):
        ...
        return response

And second time it can output:

class Profile(object):

    def __init__(self, id, client):
        ...

    def shuffle(self, options={}):
        ...
        return response

    def reorder(self, order, options={}):
        ...
        return response

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.