Giter Club home page Giter Club logo

killbill-client-ruby's Introduction

killbill-client-ruby

Kill Bill Ruby client library.

Kill Bill compatibility

Client version Kill Bill version
0.x.y 0.16.z
1.x.y 0.18.z
2.x.y 0.20.z
3.x.y 0.22.z
4.x.y 0.24.z

Installation

Get the killbill-client gem:

gem install killbill-client

Alternatively, add the dependency in your Gemfile:

gem 'killbill-client'

Authentication

A username and password can be set directly in the options hash (accepted by each API method):

options = {
  :username => 'admin',
  :password => 'password'
}

These credentials are validated by Kill Bill either directly (users managed by Kill Bill) or via a third-party (LDAP, Okta, Auth0, etc.).

Alternatively, a bearer token can be passed as such:

options = {
  :bearer => 'token'
}

The security token would be validated by Kill bill via a third-party (e.g. Auth0).

By default, Kill Bill won't maintain sessions, except when calling the API /1.0/kb/security/permissions (JSESSIONID, present in the Set-Cookie response header). This session id can be passed instead:

options = {
  :session_id => 'JSESSIONID'
}

Using this session mechanism is recommend for user interfaces or to minimize the runtime dependency with a third-party provider.

Note: if a timed out session is re-used (last_access_time older than 60 minutes by default), a HTTP/1.1 401 Unauthorized is returned with Set-Cookie: JSESSIONID=deleteMe, and the session is deleted from the database (and cache) on the server side.

Examples

Here is a snippet creating your first account and subscription:

require 'killbill_client'

KillBillClient.url = 'http://127.0.0.1:8080'

# Multi-tenancy and RBAC credentials
options = {
  :username => 'admin',
  :password => 'password',
  :api_key => 'bob',
  :api_secret => 'lazar'
}

# Audit log data
user = 'me'
reason = 'Going through my first tutorial'
comment = 'I like it!'

# Create an account
account = KillBillClient::Model::Account.new
account.name = 'John Doe'
account.first_name_length = 4
account.external_key = 'john-doe'
account.currency = 'USD'
account = account.create(user, reason, comment, options)

# Add a subscription
subscription = KillBillClient::Model::Subscription.new
subscription.account_id = account.account_id
subscription.product_name = 'Sports'
subscription.product_category = 'BASE'
subscription.billing_period = 'MONTHLY'
subscription.price_list = 'DEFAULT'
subscription = subscription.create(user, reason, comment, nil, true, options)

# List invoices
account.invoices(true, options).each do |invoice|
  puts invoice.inspect
end

The following script will tag a list of accounts with OVERDUE_ENFORCEMENT_OFF and AUTO_PAY_OFF:

require 'killbill_client'

KillBillClient.url = 'http://127.0.0.1:8080'

AUDIT_USER = 'pierre (via ruby script)'

File.open(File.dirname(__FILE__) + '/accounts.txt').readlines.map(&:chomp).each do |kb_account_id|
  account = KillBillClient::Model::Account.find_by_id kb_account_id
  puts "Current tags for #{account.name} (#{account.account_id}): #{account.tags.map(&:tag_definition_name).join(', ')}"

  account.add_tag 'OVERDUE_ENFORCEMENT_OFF', AUDIT_USER
  account.add_tag 'AUTO_PAY_OFF', AUDIT_USER

  puts "New tags for #{account.name} (#{account.account_id}): #{account.tags.map(&:tag_definition_name).join(', ')}"
end

We have lots of examples in our integration tests.

Tests

To run the integration tests:

rake test:remote:spec

You need to set in spec/spec_helper.rb the url of your instance, e.g. KillBillClient.url = 'http://127.0.0.1:8080' and the username and password to authenticate the API, e.g. KillBillClient.username = 'admin' and KillBillClient.password = 'password'

License

The Kill Bill Ruby client is released under the Apache license.

killbill-client-ruby's People

Contributors

alenad avatar andrenpaes avatar bolshakov avatar daliwei avatar devaroop avatar killbillio avatar kmanuk avatar neilw avatar pierre avatar reshmabidikar avatar sbrossie avatar tungleduyxyz avatar wwjbatista avatar wwjfrodriguez 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

Watchers

 avatar  avatar  avatar  avatar  avatar

killbill-client-ruby's Issues

Implement missing calls

Go through our resources and make sure the following API calls are implemented:

  • All APIs in AccountResource
  • All APIs in BundleResource
  • All APIs in CatalogResource
  • All APIs in CreditResource
  • All APIs in InvoicePaymentResource
  • All APIs in InvoiceResource
  • All APIs in PaymentMethodResource
  • All APIs in PaymentResource
  • All APIs in SubscriptionResource

Notes:

  • To be done on the work-for-release-0.19.x branch only
  • Create one PR per Resource to simplify the review
  • For testing, add new (or update existing) Kill Bill integration tests

NoMethodError (undefined method `require_multi_tenant_options!' for KillBillClient::Model::Catalog:Class)

When trying to upload a catalog with the latest UI:

NoMethodError (undefined method `require_multi_tenant_options!' for KillBillClient::Model::Catalog:Class):
  gems/gems/killbill-client-0.10.6/lib/killbill_client/models/catalog.rb:45:in `upload_tenant_catalog'
  gems/gems/kaui-0.8.3/app/models/kaui/admin_tenant.rb:6:in `upload_catalog'
  gems/gems/kaui-0.8.3/app/controllers/kaui/admin_tenants_controller.rb:75:in `upload_catalog'

Write missing Ruby code

Issue with Ruby client

Description : the endpoints https://killbill.github.io/slate/payment.html#complete-an-existing-transaction-using-paymentexternalkey and https://killbill.github.io/slate/payment.html#void-an-existing-payment-using-paymentexternalkey error out when external key is passed as the parameter, even though the payment state is successfully updated. Example codes below :

user = 'user'
reason = 'reason'
comment = 'comment'

transaction = KillBillClient::Model::Transaction.new
transaction.payment_external_key = "payment2-121268-void"

transaction.void(user,reason,comment,options)


user = 'user'
reason = 'reason'
comment = 'comment'

transaction = KillBillClient::Model::Transaction.new
transaction.payment_external_key = "example_payment_external_key"
refresh_options = nil

transaction.complete(user, reason,comment,options,refresh_options)

Errors :

H:/Ruby26-x64/lib/ruby/gems/2.6.0/gems/killbill-client-3.3.1/lib/killbill_client/api/net_http_adapter.rb:236:in request': {"className":"java.lang.IllegalArgumentException","code":null,"message":"Payment externalKey needs to be specified","causeClassName":null,"causeMessage":null,"stackTrace":[]} (KillBillClient::API::BadRequest)
from H:/Ruby26-x64/lib/ruby/gems/2.6.0/gems/killbill-client-3.3.1/lib/killbill_client/api/api.rb:43:in get' from H:/Ruby26-x64/lib/ruby/gems/2.6.0/gems/killbill-client-3.3.1/lib/killbill_client/models/resource.rb:43:in get'
from H:/Ruby26-x64/lib/ruby/gems/2.6.0/gems/killbill-client-3.3.1/lib/killbill_client/models/pay from H:/Ruby26-x64/lib/ruby/gems/2.6.0/gems/killbill-client-3.3.1/lib/killbill_client/models/transaction.rb:124:in block in void' from H:/Ruby26-x64/lib/ruby/gems/2.6.0/gems/killbill-client-3.3.1/lib/killbill_client/models/transaction.rb:238:in refresh_payment_with_failure_handling'
from H:/Ruby26-x64/lib/ruby/gems/2.6.0/gems/killbill-client-3.3.1/lib/killbill_client/models/transaction.rb:115:in void' from H:/GitHub/killbill/master/killbill-client-ruby/test/demo.rb:31:in

Investigate NullPointerException when retrieving tags

See https://circleci.com/gh/killbill/killbill-client-ruby/307

  1) KillBillClient::Model should manipulate accounts
     Failure/Error: raise ResponseError.error_for(code, request, response)
     
     KillBillClient::API::BadRequest:
       {"className":"java.lang.NullPointerException","code":null,"message":null,"causeClassName":null,"causeMessage":null,"stackTrace":[]}
     # ./lib/killbill_client/api/net_http_adapter.rb:217:in `request'
     # ./lib/killbill_client/api/api.rb:43:in `get'
     # ./lib/killbill_client/models/resource.rb:43:in `get'
     # ./lib/killbill_client/models/helpers/tag_helper.rb:67:in `tags'
     # ./spec/killbill_client/remote/model_spec.rb:161:in `(root)'


2018-03-21T08:02:45,993+0000 lvl='INFO', log='LoggingFilter', th='catalina-exec-1', xff='', rId='ded09cbb-bbca-4b8b-8b53-4b8c79596f5f', aRId='', tRId='3', 37 * Server in-bound request
37 > GET http://127.0.0.1:8080/1.0/kb/invoiceItems/f2d06e1b-ef93-44f8-93f7-307113199f43/tags?includedDeleted=false&audit=NONE
37 > accept: application/json
37 > user-agent: killbill/2.1.0; jruby 1.7.26 (2.0.0p598) 2016-08-26 69763b8 on OpenJDK 64-Bit Server VM 1.8.0_151-8u151-b12-0ubuntu0.16.04.2-b12 +jit [linux-amd64]
37 > accept-encoding: gzip;q=1.0,deflate;q=0.6,identity;q=0.3
37 > x-killbill-apikey: 152161935766
37 > x-killbill-apisecret: ************
37 > authorization: **************************
37 > host: 127.0.0.1:8080
37 > 

2018-03-21T08:02:45,999+0000 lvl='WARN', log='RuntimeExceptionMapper', th='catalina-exec-1', xff='', rId='ded09cbb-bbca-4b8b-8b53-4b8c79596f5f', aRId='', tRId='3', Exception : null
2018-03-21T08:02:46,005+0000 lvl='WARN', log='RuntimeExceptionMapper', th='catalina-exec-1', xff='', rId='ded09cbb-bbca-4b8b-8b53-4b8c79596f5f', aRId='', tRId='3', Exception : null
2018-03-21T08:02:46,010+0000 lvl='WARN', log='LoggingResponse', th='catalina-exec-1', xff='', rId='ded09cbb-bbca-4b8b-8b53-4b8c79596f5f', aRId='', tRId='3', Bad request
java.lang.NullPointerException: null
	at java.util.UUID.fromString(UUID.java:192)
	at org.killbill.billing.jaxrs.resources.InvoiceItemResource.getTags(InvoiceItemResource.java:156)
	at org.killbill.commons.skeleton.metrics.TimedResourceInterceptor.invoke(TimedResourceInterceptor.java:69)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at com.sun.jersey.spi.container.JavaMethodInvokerFactory$1.invoke(JavaMethodInvokerFactory.java:60)
	at com.sun.jersey.server.impl.model.method.dispatch.AbstractResourceMethodDispatchProvider$ResponseOutInvoker._dispatch(AbstractResourceMethodDispatchProvider.java:205)
	at com.sun.jersey.server.impl.model.method.dispatch.ResourceJavaMethodDispatcher.dispatch(ResourceJavaMethodDispatcher.java:75)
	at com.sun.jersey.server.impl.uri.rules.HttpMethodRule.accept(HttpMethodRule.java:302)
	at com.sun.jersey.server.impl.uri.rules.RightHandPathRule.accept(RightHandPathRule.java:147)
	at com.sun.jersey.server.impl.uri.rules.ResourceClassRule.accept(ResourceClassRule.java:108)
	at com.sun.jersey.server.impl.uri.rules.RightHandPathRule.accept(RightHandPathRule.java:147)
	at com.sun.jersey.server.impl.uri.rules.RootResourceClassesRule.accept(RootResourceClassesRule.java:84)
	at com.sun.jersey.server.impl.application.WebApplicationImpl._handleRequest(WebApplicationImpl.java:1542)
	at com.sun.jersey.server.impl.application.WebApplicationImpl._handleRequest(WebApplicationImpl.java:1473)
	at com.sun.jersey.server.impl.application.WebApplicationImpl.handleRequest(WebApplicationImpl.java:1419)
	at com.sun.jersey.server.impl.application.WebApplicationImpl.handleRequest(WebApplicationImpl.java:1409)
	at com.sun.jersey.spi.container.servlet.WebComponent.service(WebComponent.java:409)
	at com.sun.jersey.spi.container.servlet.ServletContainer.service(ServletContainer.java:558)
	at com.sun.jersey.spi.container.servlet.ServletContainer.service(ServletContainer.java:733)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:742)
	at com.google.inject.servlet.ServletDefinition.doServiceImpl(ServletDefinition.java:286)
	at com.google.inject.servlet.ServletDefinition.doService(ServletDefinition.java:276)
	at com.google.inject.servlet.ServletDefinition.service(ServletDefinition.java:181)
	at com.google.inject.servlet.ManagedServletPipeline.service(ManagedServletPipeline.java:91)
	at com.google.inject.servlet.FilterChainInvocation.doFilter(FilterChainInvocation.java:85)
	at org.killbill.billing.server.security.TenantFilter.doFilter(TenantFilter.java:110)
	at com.google.inject.servlet.FilterChainInvocation.doFilter(FilterChainInvocation.java:82)
	at org.killbill.billing.server.filters.ResponseCorsFilter.doFilter(ResponseCorsFilter.java:75)
	at com.google.inject.servlet.FilterChainInvocation.doFilter(FilterChainInvocation.java:82)
	at ch.qos.logback.classic.helpers.MDCInsertingServletFilter.doFilter(MDCInsertingServletFilter.java:49)
	at com.google.inject.servlet.FilterChainInvocation.doFilter(FilterChainInvocation.java:82)
	at com.google.inject.servlet.ManagedFilterPipeline.dispatch(ManagedFilterPipeline.java:120)
	at com.google.inject.servlet.GuiceFilter.doFilter(GuiceFilter.java:135)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
	at org.apache.shiro.guice.web.SimpleFilterChain.doFilter(SimpleFilterChain.java:44)
	at org.apache.shiro.web.servlet.AdviceFilter.executeChain(AdviceFilter.java:108)
	at org.apache.shiro.web.servlet.AdviceFilter.doFilterInternal(AdviceFilter.java:137)
	at org.apache.shiro.web.servlet.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:125)
	at org.apache.shiro.guice.web.SimpleFilterChain.doFilter(SimpleFilterChain.java:41)
	at org.apache.shiro.web.servlet.AbstractShiroFilter.executeChain(AbstractShiroFilter.java:449)
	at org.apache.shiro.web.servlet.AbstractShiroFilter$1.call(AbstractShiroFilter.java:365)
	at org.apache.shiro.subject.support.SubjectCallable.doCall(SubjectCallable.java:90)
	at org.apache.shiro.subject.support.SubjectCallable.call(SubjectCallable.java:83)
	at org.apache.shiro.subject.support.DelegatingSubject.execute(DelegatingSubject.java:383)
	at org.apache.shiro.web.servlet.AbstractShiroFilter.doFilterInternal(AbstractShiroFilter.java:362)
	at org.apache.shiro.web.servlet.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:125)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
	at com.codahale.metrics.servlet.AbstractInstrumentedFilter.doFilter(AbstractInstrumentedFilter.java:111)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
	at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:198)
	at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96)
	at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:478)
	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:140)
	at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:80)
	at org.apache.catalina.valves.rewrite.RewriteValve.invoke(RewriteValve.java:279)
	at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:624)
	at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87)
	at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:342)
	at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:799)
	at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)
	at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:868)
	at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1455)
	at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
	at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
	at java.lang.Thread.run(Thread.java:748)
2018-03-21T08:02:46,011+0000 lvl='INFO', log='LoggingFilter', th='catalina-exec-1', xff='', rId='ded09cbb-bbca-4b8b-8b53-4b8c79596f5f', aRId='', tRId='3', 37 * Server out-bound response
37 < 400
37 < Content-Type: application/json
37 < 

Add support for target phase type when changing plan

change_plan should pass the :phaseType if set in the body:

def change_plan(input, user = nil, reason = nil, comment = nil,
requested_date = nil, billing_policy = nil, call_completion = false, options = {})
params = {}
params[:callCompletion] = call_completion
params[:requestedDate] = requested_date unless requested_date.nil?
params[:billingPolicy] = billing_policy unless billing_policy.nil?
# Make sure account_id is set
input[:accountId] = @account_id
input[:productCategory] = @product_category
return self.class.put "#{KILLBILL_API_ENTITLEMENT_PREFIX}/#{@subscription_id}",
input.to_json,
params,
{
:user => user,
:reason => reason,
:comment => comment,
}.merge(options)
end

  1. Verify the implementation by getting rid of the custom implementation here: https://github.com/killbill/killbill-integration-tests/blob/beb56fc1b7269a512fb14aec9f415bb6be14115e/killbill-integration-tests/core/test_entitlement_change_skip_phase.rb#L7-L37.
  2. API docs to update

Background: killbill/killbill#704.

Document

Hi, do you have any document to describe how to use this client? Thanks!

Fix incorrect ruby code

The Ruby code is incorrect for the following methods:

  • Delete subscription custom fields - The API endpoint allows deleting multiple custom fields when multiple customField query parameters are specified. Refer to the Query Parameters section. However, the Ruby code only allows specifying a single custom field. So, the Ruby code needs to be updated so it can accept multiple customField values and pass these to the server side.
  • Add Subscription Custom Fields - This API endpoint allows adding multiple custom fields to a subscription at once. However, the Ruby code only allows specifying a single custom field and needs to be updated
  • - Modify subscription custom fields - This API endpoint allows modifying multiple custom fields at once. However, the Ruby code only allows specifying a single custom field and needs to be updated
  • Add Subscription Tags - This API endpoint allows adding multiple tags to a subscription at once. However, the Ruby code only allows specifying a single tag and needs to be updated
  • Delete Subscription Tags - This API endpoint allows deleting multiple tags from a subscription at once. However, the Ruby code only allows specifying a single tag and needs to be updated
  • Payment methods custom fields section - None of the code snippets in this section work. They cause a undefined method error. I think this is because payment_method.rb does not include CustomFieldHelper as done in subscription.rb.
  • Add Payment Method Custom Field and Delete Payment Method Custom Field - These endpoints need to be updated to allow creating/deleting multiple custom fields
  • The Retrieve Subscription by Id accepts a AUDIT but this is not present in the Ruby code and needs to be added.
  • The Retrieve Subscription by Key accepts a AUDIT query parameter but this is not present in the Ruby code and needs to be added.
  • The Retrieve Payment Method by Id accepts an AUDIT query parameter/ pluginProperties query parameter but this is not present in the Ruby code and needs to be added.
  • The Retrieve Payment Method by Key accepts an AUDIT / pluginProperties query parameter but this is not present in the Ruby code and needs to be added.
  • The Retrieve Payment by Transaction Id accepts an AUDIT / pluginProperties query parameter but this is not present in the Ruby code and needs to be added.
  • The Retrieve Payment by Transaction Key accepts an AUDIT / pluginProperties query parameter but this is not present in the Ruby code and needs to be added.
  • Payment transaction custom fields section - None of the code snippets in this section work. They cause a undefined method error. I think this is because transaction.rb does not include CustomFieldHelper as done in subscription.rb.
  • - Payment transaction tags section - None of the code snippets in this section work. They cause an undefined method error. I think this is because transaction.rb does not include TagHelper as done in subscription.rb.
  • Trigger an invoice generation for all parked accounts - The Ruby code for this endpoint does not accept the reason, comment parameters. I think this is required.
  • Update the state of a paymentTransaction and associated payment - The endpoint requires a JSON request body corresponding to the AdminPayment resource object. See shell code for this endpoint. However, the Ruby code does not accept a JSON body. This needs to be fixed.
  • Get Queue Entries endpoint accepts multiple parameters corresponding to queueName, serviceName, withHistory, etc. However, the Ruby method does not accept the corresponding parameters and thus needs to be updated.
  • Retrieve Invoice By Id - This endpoint accepts a query parameter called withChildrenItems. However the corresponding Ruby method does not accept this parameter and needs to be updated.
  • Retrieve Invoice By Number - This endpoint accepts a query parameter called withChildrenItems. However the corresponding Ruby method does not accept this parameter and needs to be updated.
  • - Generate Invoice Dry Run - The Ruby code for this endpoint does not accept the reason, comment parameters. I think this is required.
  • Add Invoice Custom Fields - This API endpoint allows adding multiple custom fields to an invoice at once. However, the Ruby code only allows specifying a single custom field and needs to be updated
  • Modify invoice custom fields - This API endpoint allows modifying multiple custom fields at once. However, the Ruby code only allows specifying a single custom field and needs to be updated
  • Delete invoice custom fields - The API endpoint allows deleting multiple custom fields when multiple customField query parameters are specified. Refer to the Query Parameters section. However, the Ruby code only allows specifying a single custom field. So, the Ruby code needs to be updated so it can accept multiple customField values and pass these to the server side.
  • Add Invoice Tags - This API endpoint allows adding multiple tags to an invoice at once. However, the Ruby code only allows specifying a single tag and needs to be updated
  • Delete Invoice Tags - This API endpoint allows deleting multiple tags from an invoice at once. However, the Ruby code only allows specifying a single tag and needs to be updated
  • Add Invoice Item Custom Fields - This API endpoint allows adding multiple custom fields to an invoice item at once. However, the Ruby code only allows specifying a single custom field and needs to be updated
  • Modify Invoice Item Custom Fields - This API endpoint allows modifying multiple custom fields at once. However, the Ruby code only allows specifying a single custom field and needs to be updated
  • Delete Invoice Item Custom Fields - The API endpoint allows deleting multiple custom fields when multiple customField query parameters are specified. However, the Ruby code only allows specifying a single custom field and needs to be updated.
  • Delete Invoice Item Tags - his API endpoint allows deleting multiple tags from an invoice item at once. However, the Ruby code only allows specifying a single tag and needs to be updated

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.