Giter VIP home page Giter VIP logo

cpv-framework's Introduction

C++ web framework based on seastar framework

Codacy Badge Build Status license GitHub release

cpv framework is a web framework written in c++ based on seastar framework, it focus on high performance and modular design.

seastar framework is an application framework that use the share nothing programming model, which isolate resources explicitly for each cpu core. cpv framework use this model too, a cpv application will initialize services on each cpu core, execute them on each cpu core and avoid sharing data between cpu cores, you don't need thread locks or atomic variables in cpv application because all code will be thread safe by design.

In addition, cpv framework avoid memory copies by using reference counted slice of string (cpv::SharedString) and scattered message (cpv::Packet) everywhere. You can get a slice of url path, query parameter, http header, and body content of request from the original packet without allocate a new string and copy them (there few cases require copy such as http header value splited in two packets, or query parameter different after decoded), and you can construct a scattered message contains multiple non-continuous fragments as http response body (based on posix vectored I/O api).

For more features, see the feature list and documents below.

Features

  • Isolate resources explicitly between cpu cores
  • Avoid memory copies by using cpv::SharedString and cpv::Packet everywhere
  • Future promise based asynchronous interface
  • Dependency injection container
  • Modular design
    • Modules decide what to do when application start and stop
    • Modules register services to dependency injection container and retrive services from it
  • Http server
    • Supports Http 1.0/1.1 (based on http-parser)
    • Supports pipeline
    • Supports chaining multiple request handlers (middleware style)
    • Supports full and wildcard url routing (by using routing handler)
    • Provide stream interface for request body and response body
    • Provide static file handler, supports pre compressed gzip, bytes range, If-Modified-Since detection and lru memory cache
  • Serialization
    • Provide json serializer and deserializer (based on sajson)
    • Provide http form serializer and deserializer

You can also check the roadmap to see which features will be added in the next release.

Getting Started

Install cpv framework

If you're using ubuntu 18.04, you can install cpv framework from PPA, this is the easiest way:

sudo apt-get install software-properties-common
sudo add-apt-repository ppa:compiv/cpv-project
sudo apt-get update
sudo apt-get install cpvframework

In addition, you need gcc-9 to compile cpv application.

sudo add-apt-repository -y ppa:ubuntu-toolchain-r/test
sudo apt-get install g++-9

If you're using other linux distribution, you can install from source:

# please ensure seastar framework is installed
# please ensure `pkg-config --cflags seastar` works
# please ensure `pkg-config --libs seastar` works

mkdir -p build/cpvframework-custom
cd build/cpvframework-custom
cmake -DCMAKE_BUILD_TYPE=RelWithDebInfo \
	-DCMAKE_C_COMPILER=gcc-9 \
	-DCMAKE_CXX_COMPILER=g++-9 \
	../../src
make V=1
make install V=1

If you're using windows or macosx, you can use docker with ubuntu 18.04 image because seastar framework is basiclly linux only.

Write a hello world application

This is the source code of a hello world cpv application, it's same as examples/HelloWorld/Main.cpp:

#include <seastar/core/app-template.hh>
#include <CPVFramework/Application/Application.hpp>
#include <CPVFramework/Application/Modules/LoggingModule.hpp>
#include <CPVFramework/Application/Modules/HttpServerModule.hpp>
#include <CPVFramework/Application/Modules/HttpServerRoutingModule.hpp>
#include <CPVFramework/Http/HttpResponseExtensions.hpp>

int main(int argc, char** argv) {
	seastar::app_template app;
	app.run(argc, argv, [] {
		cpv::Application application;
		application.add<cpv::LoggingModule>();
		application.add<cpv::HttpServerModule>([] (auto& module) {
			module.getConfig().setListenAddresses({ "0.0.0.0:8000", "127.0.0.1:8001" });
		});
		application.add<cpv::HttpServerRoutingModule>([] (auto& module) {
			module.route(cpv::constants::GET, "/", [] (cpv::HttpContext& context) {
				return cpv::extensions::reply(context.getResponse(), "Hello World!");
			});
		});
		return application.runForever();
	});
	return 0;
}

It creates a cpv application, add 3 modules, route GET "/" to a custom handle function which replies "Hello World!" and run the cpv application on seastar framework forever (until Ctrl+C pressed).

Compile and execute the hello world application

Now you can compile the hello world application:

g++-9 $(pkg-config --cflags seastar) \
	$(pkg-config --cflags cpvframework) \
	hello.cpp \
	$(pkg-config --libs seastar) \
	$(pkg-config --libs cpvframework)

And execute it with:

# --reactor-backend epoll is recommended because it's stable but not required
./a.out --reactor-backend epoll

It will initialize services and handle requests like this graphic describe (assume it used 2 cpu cores):

example-app-design

Finally you can test the application with curl:

curl -v http://localhost:8000

Documents

Examples

Benchmark results

To see history results please check the change log of the wiki page.

Running Tests

Please check tests/travis_run_tests.sh for how to setup a environment for testing and run the tests.

Contribution

You should follow these rules when contributing code, pull request or patch is welcome.

  • Use tabs instead of spaces
  • For class names, use camel case and start with a upper case (e.g. SomeClass)
  • For function names, use camel case and start with a lower case (e.g. someFunction)
  • For local variable names, use camel case and start with a lower case (e.g. someInt)
  • For global variable names, use camel case and start with a upper case (e.g. SomeGlobalValue)
  • For class member names, use camel case and start with a lower case and ends with _ (e.g. someMember_)
  • Write comments for every public class and function, keep the code as simple as possible

License

LICENSE: MIT LICENSE
Copyright © 2018-2020 303248153@github
If you have any license issue please contact [email protected].

cpv-framework's People

Contributors

303248153 avatar compiv avatar dudes-come 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

cpv-framework's Issues

Application and module system design draft

type definition:

class Application
	class Service (implement in src)
		Container container
		std::vector<std::tuple<
			std::unique_ptr<ModuleBase>,
			std::function<void(ModuleBase*)>> modules
		bool initialized // disallow register after initialized (first start)
		seastar::future<> start()
		seastar::future<> stop()
	seastar::shared_ptr<seastar::shareded<Service>> service_

	template <class Module>
	void add()
	template <class Module>
	void add(std::function<void(Module&)> initFunc); // check static_cast<ModuleBase, Module> address is equal or not
	void add(std::unique_ptr<ModuleBase>, std::function<void(ModuleBase*)> initFunc); // implement in src

	seastar::future<> start() // should do_with copy of service_
	seastar::future<> stop() // should do_with copy of service_
	seastar::future<> run_forever() // should do_with copy of service_

	Application()

enum ApplicationState
	StartInitialize
	RegisterBasicServices
	BeforeCallCustomInitializeFunctions
	CallingCustomInitializeFunctions // dummy state, won't invoke module.handle
	AfterCustomInitializeFunctionsCalled
	RegisterHeadServices
	RegisterServices
	RegisterTailServices
	PatchServices
	AfterServicesRegistered
	AfterInitialized
	BeforeStart // will call for each start
	Starting // will call for each start
	AfterStarted // will call for each start
	BeforeStop // will call for each stop
	Stopping // will call for each stop
	AfterStopped // will call for each stop

class ModuleBase
	virtual ~ModuleBase() = default;
	virtual seastar::future<> handle(Container& container, ApplicationState state) = 0;

class HttpContext
	HttpRequest request
	HttpResponse response
	seastar::socket_address clientAddress
	Container container // shared by all concurrent requests on the same core
	ServiceStorage serviceStorage // used only in this request, clear after request finished

files to add:

Application
	Application.hpp
	ModuleBase.hpp
	Modules
		LoggingModule.hpp
		HttpServerModule.hpp
		HttpServerRoutingModule.hpp
Http
	HttpContext.hpp
HttpServer
	Handlers
		HttpServerRequestRoutingHandler.hpp
		HttpServerRequestFunctionHandler.hpp
		HttpServerRequestStaticFileHandler.hpp
	Routing
		HttpServerRouteTable.hpp
		HttpServerRouteHandlerBase.hpp
		HttpServerRouteFunctionHandler.hpp
		HttpServerRouteControllerHandler.hpp

api usage:

using namespace cpv;
Application app;
app.add<LoggingModule>([] (auto& module) {
	module.setLogger(Logger::CreateConsole(LogLevel::Info));
});
app.add<HttpServerModule>([] (auto& module) {
	auto& config = module.getConfig();
	config.setListenAddresses({ "0.0.0.0:80" });
	config.set404Handler([] (HttpResponse& response) {
		return extensions::redirectTo(response, "/404");
	});
});
app.add<HttpServerStaticFileModule>([] (auto& module) {
	module.map("/static", "./static");
});
app.add<HttpServerRoutingModule>([] (auto& module) {
        using namespace cpv::constants;
	auto& routeTable = module.getRouteTable();
	routeTable.route(GET, "/", [] (HttpResponse& response) {
		return extensions::replyStaticText(response, "Hello World!");
	});
	routeTable.route(GET, "/hello", [] (HttpResponse& response) {
		return extensions::replyString(response, "Hello!");
	});
	// TODO: handle url matching and parse parts
	// TODO: handle dependency injection (controller)
});
app.add<ExampleModule>();
return app.run_forever()

addition:

rules
- request handler could use container and storage inside http context to get services
- route handler holds controller and decide which action to execute
    - api: route(GET, "/", [] (HttpContext& context) { ... })
    - example:
        - route function handler<Func> { operate()(HttpContext& context) { f(context) } Func f; }
        - route controller handler <Controller, Action, Service...> { operator()(HttpContext& context) { c->*action(context, service...) } Controller c; }

Add documents

  • HelloWorld
  • Container
    • Aop
  • HttpClient
  • HttpServer
  • Logging
  • Module
  • Application
  • Metrics
  • Benchmark

Provide abstract http client and factory (injectable)

HttpClient (interface, with vdtor)
HttpRequest (interface, with vdtor)
HttpResponse (interface, with vdtor)
HttpClientFactory (interface, with vdtor)
HttpClientImpl
HttpRequestImpl
HttpResponseImpl
HttpClientFactoryImpl (with (host,port) => client map)

example:

HttpClientFactory factory = HttpClientFactory::create();
seastar::shared_ptr<HttpClient> client = factory.create("localhost", 8000);
std::unique_ptr<HttpRequest> request = client.makeRequest("GET", "/index.html");
client.send(std::move(request)).then([] (std::unique_ptr<HttpResponse> response) { });

Main.cpp is failing with segementation fault

Hello,

I ran Main.cpp file in the example section. But I am getting the following segmentation fault.

WARN 2022-06-16 15:50:23,732 [shard 0] seastar - Creation of perf_event based stall detector failed, falling back to posix timer: std::system_error (error system:13, perf_event_open() failed: Permission denied)
WARN 2022-06-16 15:50:23,734 [shard 0] seastar - Unable to set SCHED_FIFO scheduling policy for timer thread; latency impact possible. Try adding CAP_SYS_NICE
DEBUG 2022-06-16 15:50:23,734 [shard 0] seastar - generate_config dev_id: 0
INFO 2022-06-16 15:50:23,734 [shard 0] seastar - Created fair group io-queue-0, capacity rate 2147483:2147483, limit 12582912, rate 16777216 (factor 1.0), threshold 2000
INFO 2022-06-16 15:50:23,734 [shard 0] seastar - Created io group dev(0), length limit 4194304:4194304, rate 2147483647:2147483647
DEBUG 2022-06-16 15:50:23,734 [shard 0] seastar - allocate 0 IO group
INFO 2022-06-16 15:50:23,734 [shard 0] seastar - Created io queue dev(0) capacities: 512:2000/2000 1024:3000/3000 2048:5000/5000 4096:9000/9000 8192:17000/17000 16384:33000/33000 32768:65000/65000 65536:129000/129000 131072:257000/257000
DEBUG 2022-06-16 15:50:23,734 [shard 0] seastar - attached 0 queue to 0 IO group
TRACE 2022-06-16 15:50:23,778 [shard 4] exception - Throw exception at:
0x581bad 0x581e8a 0x582319 0x45a32c 0x45a5a8 /lib64/libstdc++.so.6+0xb50cb 0x428e74 0x4b69e3 0x4d608b 0x4d69a5 0x4d8e8f 0x492aad /lib64/libpthread.so.0+0x8179 /lib64/libc.so.6+0xfcdc2
WARN 2022-06-16 15:50:23,778 [shard 4] seastar - Creation of perf_event based stall detector failed, falling back to posix timer: std::system_error (error system:13, perf_event_open() failed: Permission denied)
TRACE 2022-06-16 15:50:23,779 [shard 2] exception - Throw exception at:
0x581bad 0x581e8a 0x582319 0x45a32c 0x45a5a8 /lib64/libstdc++.so.6+0xb50cb 0x428e74 0x4b69e3 0x4d608b 0x4d69a5 0x4d8e8f 0x492aad /lib64/libpthread.so.0+0x8179 /lib64/libc.so.6+0xfcdc2
WARN 2022-06-16 15:50:23,779 [shard 2] seastar - Creation of perf_event based stall detector failed, falling back to posix timer: std::system_error (error system:13, perf_event_open() failed: Permission denied)
TRACE 2022-06-16 15:50:23,780 [shard 5] exception - Throw exception at:
0x581bad 0x581e8a 0x582319 0x45a32c 0x45a5a8 /lib64/libstdc++.so.6+0xb50cb 0x428e74 0x4b69e3 0x4d608b 0x4d69a5 0x4d8e8f 0x492aad /lib64/libpthread.so.0+0x8179 /lib64/libc.so.6+0xfcdc2
WARN 2022-06-16 15:50:23,780 [shard 5] seastar - Creation of perf_event based stall detector failed, falling back to posix timer: std::system_error (error system:13, perf_event_open() failed: Permission denied)
DEBUG 2022-06-16 15:50:23,782 [shard 4] seastar - attached 4 queue to 0 IO group
DEBUG 2022-06-16 15:50:23,782 [shard 5] seastar - attached 5 queue to 0 IO group
DEBUG 2022-06-16 15:50:23,782 [shard 2] seastar - attached 2 queue to 0 IO group
TRACE 2022-06-16 15:50:23,784 [shard 7] exception - Throw exception at:
0x581bad 0x581e8a 0x582319 0x45a32c 0x45a5a8 /lib64/libstdc++.so.6+0xb50cb 0x428e74 0x4b69e3 0x4d608b 0x4d69a5 0x4d8e8f 0x492aad /lib64/libpthread.so.0+0x8179 /lib64/libc.so.6+0xfcdc2
WARN 2022-06-16 15:50:23,784 [shard 7] seastar - Creation of perf_event based stall detector failed, falling back to posix timer: std::system_error (error system:13, perf_event_open() failed: Permission denied)
TRACE 2022-06-16 15:50:23,784 [shard 6] exception - Throw exception at:
0x581bad 0x581e8a 0x582319 0x45a32c 0x45a5a8 /lib64/libstdc++.so.6+0xb50cb 0x428e74 0x4b69e3 0x4d608b 0x4d69a5 0x4d8e8f 0x492aad /lib64/libpthread.so.0+0x8179 /lib64/libc.so.6+0xfcdc2
WARN 2022-06-16 15:50:23,784 [shard 6] seastar - Creation of perf_event based stall detector failed, falling back to posix timer: std::system_error (error system:13, perf_event_open() failed: Permission denied)
TRACE 2022-06-16 15:50:23,785 [shard 3] exception - Throw exception at:
0x581bad 0x581e8a 0x582319 0x45a32c 0x45a5a8 /lib64/libstdc++.so.6+0xb50cb 0x428e74 0x4b69e3 0x4d608b 0x4d69a5 0x4d8e8f 0x492aad /lib64/libpthread.so.0+0x8179 /lib64/libc.so.6+0xfcdc2
WARN 2022-06-16 15:50:23,785 [shard 3] seastar - Creation of perf_event based stall detector failed, falling back to posix timer: std::system_error (error system:13, perf_event_open() failed: Permission denied)
DEBUG 2022-06-16 15:50:23,787 [shard 3] seastar - attached 3 queue to 0 IO group
DEBUG 2022-06-16 15:50:23,787 [shard 7] seastar - attached 7 queue to 0 IO group
DEBUG 2022-06-16 15:50:23,787 [shard 6] seastar - attached 6 queue to 0 IO group
TRACE 2022-06-16 15:50:23,788 [shard 1] exception - Throw exception at:
0x581bad 0x581e8a 0x582319 0x45a32c 0x45a5a8 /lib64/libstdc++.so.6+0xb50cb 0x428e74 0x4b69e3 0x4d608b 0x4d69a5 0x4d8e8f 0x492aad /lib64/libpthread.so.0+0x8179 /lib64/libc.so.6+0xfcdc2
WARN 2022-06-16 15:50:23,788 [shard 1] seastar - Creation of perf_event based stall detector failed, falling back to posix timer: std::system_error (error system:13, perf_event_open() failed: Permission denied)
DEBUG 2022-06-16 15:50:23,789 [shard 1] seastar - attached 1 queue to 0 IO group
Segmentation fault on shard 0.
Backtrace:
0x4e1ccb
0x4b2f23
0x4b3664
0x4b36d2
/lib64/libpthread.so.0+0x12c1f
/lib64/libCPVFramework.so+0x1cd9c7
/lib64/libCPVFramework.so+0xeb6f2
/lib64/libCPVFramework.so+0xe7aec
/lib64/libCPVFramework.so+0xe85bd
0x43eff3
0x43fe79
0x43fb5d
0x43f6c3
0x44d3d1
0x44de4d
0x4522ca
0x4aa48d
0x4aa7b0
0x4cf565
0x4cff69
0x450746
0x4511b7
0x4512b7
0x43f0bb
/lib64/libc.so.6+0x23492
0x43ec0d
./run.sh: line 13: 2084508 Segmentation fault ${BIN_PATH} --reactor-backend epoll

I ran the seastar-addr2line and decoded the backtrace. This is what I found.

[Backtrace #0]
addr2line: Dwarf Error: Can't find .debug_ranges section.
void seastar::backtraceseastar::backtrace_buffer::append_backtrace()::{lambda(seastar::frame)#1}(seastar::backtrace_buffer::append_backtrace()::{lambda(seastar::frame)#1}&&) at ??:?
seastar::print_with_backtrace(seastar::backtrace_buffer&, bool) at reactor.cc:?
seastar::print_with_backtrace(char const*, bool) [clone .constprop.0] at reactor.cc:?
seastar::install_oneshot_signal_handler<11, &seastar::sigsegv_action>()::{lambda(int, siginfo_t*, void*)#1}::_FUN(int, siginfo_t*, void*) at reactor.cc:?
.annobin_sigaction.c at sigaction.c:?
addr2line: Dwarf Error: Can't find .debug_ranges section.
seastar::reactor::add_timer(seastar::timerstd::chrono::_V2::steady_clock*) at crtstuff.c:?
seastar::future seastar::sleep<std::chrono::_V2::steady_clock, long, std::ratio<1l, 1l> >(std::chrono::duration<long, std::ratio<1l, 1l> >) at ??:?
auto cpv::Application::runForever()::{lambda(auto:1&, auto:2&)#1}::operator()<seastar::shared_ptrcpv::ApplicationData, seastar<std::atomic > >(seastar::shared_ptrcpv::ApplicationData&, seastar<std::atomic >&) const [clone .constprop.0] at Application.cpp:?
cpv::Application::runForever() at ??:?
main::{lambda()#1}::operator()() const at Main.cpp:?
seastar::future std::__invoke_impl<seastar::future, main::{lambda()#1}&>(std::__invoke_other, main::{lambda()#1}&) at Main.cpp:?
std::enable_if<is_invocable_r_v<seastar::future, main::{lambda()#1}&>, std::enable_if>::type std::__invoke_r<seastar::future, main::{lambda()#1}&>(seastar::future&&, (main::{lambda()#1}&)...) at Main.cpp:?
std::_Function_handler<seastar::future (), main::{lambda()#1}>::_M_invoke(std::_Any_data const&) at Main.cpp:?
addr2line: Dwarf Error: found dwarf version '36730', this reader only handles version 2, 3, 4 and 5 information.
std::_Function_handler<seastar::future (), seastar::app_template::run(int, char**, std::function<seastar::future ()>&&)::{lambda()#1}>::_M_invoke(std::_Any_data const&) at app-template.cc:?
std::_Function_handler<void (), seastar::app_template::run(int, char**, std::function<seastar::future ()>&&)::{lambda()#1}>::_M_invoke(std::_Any_data const&) at app-template.cc:?
seastar::continuation<seastar::internal::promise_base_with_type, std::function<void ()>, seastar::future::then_impl_nrvo<std::function<void ()>, seastar::future >(std::function<void ()>&&)::{lambda(seastar::internal::promise_base_with_type&&, std::function<void ()>&, seastar::future_stateseastar::internal::monostate&&)#1}, void>::run_and_dispose() at ??:?
seastar::reactor::run_tasks(seastar::reactor::task_queue&) at ??:?
seastar::reactor::run_some_tasks() [clone .part.0] at reactor.cc:?
addr2line: Dwarf Error: found dwarf version '41501', this reader only handles version 2, 3, 4 and 5 information.
seastar::reactor::do_run() at ??:?
seastar::reactor::run() at ??:?
seastar::app_template::run_deprecated(int, char**, std::function<void ()>&&) at ??:?
addr2line: Dwarf Error: found dwarf version '17417', this reader only handles version 2, 3, 4 and 5 information.
seastar::app_template::run(int, char**, std::function<seastar::future ()>&&) at ??:?
addr2line: Dwarf Error: found dwarf version '45312', this reader only handles version 2, 3, 4 and 5 information.
seastar::app_template::run(int, char**, std::function<seastar::future ()>&&) at ??:?
main at ??:?
__libc_start_main at ??:?
_start at ??:?

Any help is appreciated.

Project concept, progress and roadmap (for alpha stage)

This issue is for who wants to contribute to this project recently.
Because this project still in alpha stage, documents are not ready, this issue only contains simple descriptions and will close after project reached beta release (documents will be ready then).

Project Concept:

  • Use seastar framework to manage io and tasks
    • seastar's share nothing design can elide thread locks and atomic operations
  • Avoid copy by using std::string_view and seastar::net::packet (iovec)
  • Create an advance web framework with modern architecture
    • middleware, di container, and modules

Progress (Completed Features):

  • Handle http 1 connection with nodejs's http_parser (support pipeline)
  • Middleware (HttpServerRequestHandlerBase)
  • DI Container (support constructor dependency injection and scoped lifetime)

Performance:
See #14

Roadmap:
0.1

  • (done) Improve performance
  • (done) Add application class and module system (provide a neat api for users)
  • (done) Add routing handler
  • (done) Add routing module
  • Add debian package
  • Add examples (basic example)
  • Add documents
  • Add benchmark result

(For following versions see docs/Roadmap.md)

Contribution Guide:

  • Use same code style as existing code (tab indent, no new line for {)
  • Use c++17 (will upgrade to c++20 in future for coroutine support)
  • Add test cases for each feature added

References:

If you want to add major features not listed here, you can comment on this issue.

Is there a non-blocking alternative to runForever()?

This project seems totally dead, but I thought I'd ask anyway. The design of the application class appears to presume that the cpv http server will be the only thing Seastar is running. One might want to additionally run an rpc endpoint (smf for example, but that also appears dead) or other custom Seastar code.

Aop support

Able to override factories in container for custom proxy types

Add Container::remove

void removeEntries(const std::type_index& serviceType);

template <class TService>
void remove();

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.