Giter VIP home page Giter VIP logo

is-05's Introduction

AMWA IS-05 NMOS Device Connection Management Specification

Lint Status Render Status

What does it do?

  • Provides a transport-independent way of connecting Media Nodes
    • Supports RTP, WebSocket and MQTT connections
  • Supports single + bulk connections, immediate + delayed connections

Why does it matter?

  • ST 2110 does not specify how to do this
    • So without IS-05 there is a danger of multiple proprietary approaches
    • ...and difficulty in adopting new stream formats.
  • Provides support for new specifications
    • such as IS-07 event transport

How does it work?

  • Control application sends instructions to Media Nodes
  • transport_params conveys the connection information

Getting started

There is more information about the NMOS Specifications and their GitHub repos at https://specs.amwa.tv/nmos.

is-05's People

Contributors

andrewbonney avatar garethsb avatar peterbrightwell avatar robwadge avatar simonrankine avatar

Stargazers

 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

is-05's Issues

[v1.1 review] Document what 'reflecting the current running state' means for connection-oriented transports

In Overview - Active the spec says "the active endpoint reflects the current running state of the underlying Sender or Receiver."

What this means for connection-oriented transports might usefully be clarified in the spec.

To recap: For RTP transport, this means reflecting current configuration state rather than actual 'connection state' such as whether or not an RTP Receiver is currently receiving packets. For example, it's perfectly possible the user expected no packets to be received immediately, but wanted to prime a Receiver for their arrival.

For WebSocket and MQTT, added in IS-05 v1.1, there are probably more immediately-identifiable error states. For example, address look-up failure, authorization failure, broken socket connection, ping-pong timeout, wrong IS-07 state message "event_type", etc.

Some of these examples are likely to be persistent, and some transient, but in all cases, these scenarios MUST NOT be reflected into IS-05 /active endpoint or IS-04 Sender/Receiver "subscription" unless they are identified and reported in the (error) response to the PATCH /staged request. Like the "no packets received" in the case of RTP, tracking these events fall more into the category of monitoring, which isn't currently covered by IS-05 (or any other NMOS spec).

Instead, for transient failures encountered for connection-oriented transports, devices SHOULD retry if possible, probably with exponential backoff, up to a defined limit, unless an activation explicitly changes the /active parameters. This enables graceful recovery without user interaction.

(Language that partly contradicted the above has been recently removed from IS-07 for v1.0.1 in AMWA-TV/is-07@0ecc272.)

Should IS-04 control entry for the IS-05 API have a trailing slash?

This came up at the Houston interop: The example "controls" entry for the IS-04 Device in chapter 3.1 of the documentation has a trailing slash in its "href":

"controls": [
  {
    "type": "urn:x-nmos:control:sr-ctrl/v1.0",
    "href": "http://192.168.10.3/x-nmos/connection/v1.0/"
  }
]

Similarly, the "API Paths" of section 2.1 states the format for an NMOS API MUST use a path like http(s)://<ip address or hostname>:<port>/x-nmos/<api type>/<api version>/ (note the trailing slash). However, in discussion regarding issues I submitted about this regarding the Sony implementation and the IS-04/-05 tests, there is some belief that the section titled "URLs: Approach to Trailing Slashes" in chapter 2.0 should apply, and that no trailing slashes should appear in the "controls" entries.

Presuming we can come to agreement on what the correct behavior is, can we correct the examples and/or text to match? In particular, some explicit text along with the example "controls" attribute would be helpful.

Errors during a pending activation

At present IS-05 relies on the client to notice where a pending activation has failed to happen by checking back with the API. In the event a client does check back, the API does not provide any information on the nature of such a failed activation. Possible resolutions include:

  • Providing some information about the success or failure of the previous activation in the active endpoint.
  • Providing history of previous activations at a new new endpoint, including error information.
  • Adding a websocket to IS-05 which would provide information about scheduled activations to subscribers when the are completed.

This would potentially simplify client implementations, and provide better feedback to users as to why errors occurred during activations.

/single/senders/{id}/staged describes behaviour of /transportfile. Why?

The description for /single/senders/{id}/staged GET leaves me puzzled. It recommends to return 404 for a GET request to /transportfile, which "lives" elsewhere, when master_enable isn't true.

Firstly, I don't see why 404 should be returned at all in this case. Why should one not be able to read the transportfile when master_enable is false? I'd say it is both simpler and easier to understand when there's no such dependency.

Secondly, there's no mentioning of master_enable in the description of /transportfile, so I come to think that the inconsistency may be the result of an oversight.

Activation response after unlocking

The state change on the staged endpoint isn't clear on this matter, but I believe the text "On the staged endpoint this field returns to null once the activation is completed." should be extended with "...or the resource is unlocked by setting the activation mode to null." This text appears twice in the activation response schema.

Similarly (if even more nit-picky), I believe the activation schema for requests should require that the requested_time be null if the mode is null.

IS-05 v1.1 transport_params schemas don't validate as intended

The mechanism by which we introduced the transport parameters for the additional transports' has had the unfortunate side-effect of making unexpected instances validate.

E.g. the following PATCH /single/receivers/{receiverId}/staged request body validates right now

{
  "transport_params": [
    {
      "destination_port": "foo"
    }
  ]
}

That's because although the transport params don't pass the RTP params schema, it does pass the WebSocket params schema, because the schemas don't prohibit additional properties (and have no required properties because it's valid to stage as few params as you like).

Fix PR on the way...

Use of the term "Device"

The Overview says:

The terms 'Node', 'Device', 'Sender' and 'Receiver' will be used extensively throughout this document. Please refer to the core NMOS Technical Overview for definitions of these.

It goes on to use the word "Resource" to mean either a Sender or Receiver, or just uses the phrase "Sender or Receiver" repeatedly.

However, in some of the rest of the documentation (e.g. here and here), the word "Device" or the phrase "running Device" is used to mean "Sender or Receiver". That is confusing.

I think it would be better to stick to the clunky "Sender or Receiver", or to use a new term. That might be "Resource" but that's a bit general, so perhaps something like "Connector".

How to patch the transport file to the sender?

I tried to register a single node to the registry and was able to get the transport file using the connection API. Now i am not sure of how to patch this transport file to the receiver (assuming the same node can receive as i only have one node) node. Is it possible to do so? Does it require the same id as the sender id? or do i need a different node to receive the file?

This might be a very silly question. As i am totally new into this, it would be very helpful if i could get some hint or the links to documentation leading to the solution.
Thank you.

[v1.1 review] Should MQTT transport *sender* broker_topic support 'auto'?

I don't feel strongly either way, I just noted that an MQTT sender's "broker_topic" and "connection_status_broker_topic" don't support 'auto', whereas the other MQTT transport params do support 'auto', and so does e.g. WebSocket senders' "connection_uri" - which broadly corresponds to the MQTT destination/topic properties combined.

(The same doesn't apply to receivers, and that'd be consistent with WebSocket receivers' "connection_uri".)

Document best practice for non-2022-7 Receivers handling 2022-7 SDP files

The docs in https://github.com/AMWA-TV/nmos-device-connection-management/blob/v1.0.x/docs/4.1.%20Behaviour%20-%20RTP%20Transport%20Type.md#operation-with-smpte-2022-7 cover what a 2022-7 compatible Receiver should do if it receives a non-2022-7 SDP file. They don't however cover the reverse. If a non-2022-7 Receiver is passed a 2022-7 SDP file it seems reasonable that an implementation could accept this but only receive from the first stream listed. It's questionable whether this should be part of the spec, a separate best practice or simply a suggested behaviour.

About "rtp_enabled"

Hi!

According to the RTP Behavior:

A Receiver sets the rtp_enabled parameter to true for each leg it has configured from the SDP file, unless overridden by the requested transport_params as noted below.

Is this a requirement (MUST)?

Is there any special behavior of rtp_enabled for Senders that we should take care of?

Thanks in advance.

Reflecting device limitations through scheduled activation 'requested_time'

I had a query raised earlier in the year regarding use of the requested_time attribute for scheduled activations.

The current text in https://amwa-tv.github.io/nmos-device-connection-management/tags/v1.1/APIs/schemas/resolved/activation-response-schema.html, as reflected in the testing tool is that requested_time in the activation response should match what was included in the activation request. If however a device cannot achieve nanosecond granularity in its activations (for example if it can only manage to the nearest millisecond), what would be best to reflect back in this attribute? Should it reflect the request, or should it attempt to inform the control system via the response that it is incapable of meeting the requirement and will only activate at the time specified in the returned requested_time.

This would of course open questions such as 'how far away from the original requested time is acceptable to return?' and 'should I activate earlier or later than originally requested in this case?'.

Nanoseconds vs ticks.

Hello.

I am implementing the IS-05 in .NET (C#), here the smallest unit of time is the tick (which is equal to 100 nanoseconds).

It is clear to me that in NMOS the base unit is the nanoseconds since this is how the versions and activations ("activate_scheduled_absolute" and "activate_scheduled_relative") are based.

What can I do in this case? Is it mandatory to have a base unit of nanoseconds?

Thanks in advance.

Victor.

Patching a receiver's "transport_file"

The v1.0-receiver-stage-schema.json for "transport_file" doesn't make the "data" and "type" required. Is that an oversight? It seems to me it's unfortunate to allow staging just one or other of these fields (and staging an empty object is pointless)?

Looking at it now, the "transport_file" schema ought to be extracted out of the stage/response schemas in the same way as the activation schema.

More typos

(Hit return and submitted this too soon. I may add more later...)

RAML

Several uses of "sender/receiver" are a little confusing ("hmm, are these sender wotsits really being validated against receiver thingamijigs?"). Other instances of "sender/receiver" might be OK, but using "resource" or another term (see #35) might be better. Other instances of sender or receiver are just obvious copy & paste typos.

APIs/ConnectionAPI.raml - sender/receiver --> sender (or resource?)

APIs/ConnectionAPI.raml - sender --> receiver

APIs/ConnectionAPI.raml - sender/receiver --> receiver (or resource?)

APIs/ConnectionAPI.raml - senders --> sender

APIs/ConnectionAPI.raml - sender/receiver --> sender (or resource?)

APIs/ConnectionAPI.raml - sender/receiver --> sender (or resource?)

APIs/ConnectionAPI.raml - receiver --> sender

APIs/ConnectionAPI.raml - reqest --> request

APIs/ConnectionAPI.raml - sender/receiver --> receiver (or resource?)

APIs/ConnectionAPI.raml - sender/receiver --> receiver (or resource?)

Schemas

APIs/schemas/v1.0-sender-response.schema.json - receiver --> sender

Values for /transporttype and relationship to IS-04 "transport" values

Schema for /transportfile endpoint is at https://github.com/AMWA-TV/nmos-device-connection-management/blob/v1.1-dev/APIs/schemas/transporttype-response-schema.json. This currently contains enumerated values.

I presume this should be updated to match the pattern based schema in https://github.com/AMWA-TV/nmos-discovery-registration/blob/v1.3-dev/APIs/schemas/sender.json (added by AMWA-TV/is-04@d6dfff2).

That commit also added the following in the IS-04 Common Keys documentation:

"Note: From v1.3 onwards, permitted transport types are not versioned and are instead defined via the NMOS Parameter Registers."

The table of values below that sentence, and the transport parameter register which is to be used instead of it, contains the entries for both the top-level category "urn:x-nmos:transport:rtp" and the subclassifications with ".ucast" and ".mcast" appended.

So the question arises, whether the IS-05 "/transporttype" may be any value from the parameter register, including subclassifications, or only one of the top-level categories? If so, the concept of ‘subclassifications’ and ‘top-level category’ need better definition. Can I trim to the first ‘.’ after the last ‘:’ for instance?

IS-05 v1.1-dev "connection_uri" is singular

In general, NMOS specs are written to allow redundancy and versioning of locators, e.g. by array properties for endpoints/URLs in various places in IS-04 and IS-05. The new "connection_uri" transport property is singular (and cannot be an array due to the schema for properties).

Is this a problem?

PATCH "transport_params" with empty array?

Is it valid to send a request like this?

PATCH /x-nmos/connection/v1.0/single/receivers/{receiverId}/staged

{
  "transport_params": []
}

The specification, here, uses shall regarding the number of items in the "trasnport_params" array. The schema does not validate that (the required number, one or two, would depend on whether ST 2022-7 is in use).

Note that there are two other entirely valid ways of specifying no transport parameters in the PATCH request, (a) omit "transport_params" entirely, or (b) make its value [{}] or [{}, {}] as appropriate.

Ambiguity on how to represent non-existent transportfile in receiver PATCH

Some ambiguity appears to exist regarding how to indicate that no transportfile exists in a PATCH to an RTP receiver (eg. "disconnecting" the receiver). Some implementations have chosen to send

"transport_file": {
    "type": "application/sdp",
    "data": ""
}

in this case based on wording from TR-1001-1:2018.

Based on discussions from Slack the intended way to indicate no transportfile is

"transport_file": {
    "type": null,
    "data": null
}

and if "type" is set to "application/sdp" then "data" should be expected to contain a valid SDP file which an empty string is not.

Would it be worthwhile to update the description of the receiver transportfile schema to something like

"description": "Transport file parameters. 'data' and 'type' must both be strings or both be null. If 'type' is non-null 'data' is expected to contain a valid instance of the specified media type"

to negate this ambiguity?

v1.0-bulk-stage-confirm.json does not permit a response code of 423 "Locked"

When a bulk request is attempted on a resource that is locked, shouldn't the code field in the matching element of the HTTP response contain 423 for its code field? The schema does not currently permit such a response.

I'm presuming that a bulk POST on a locked resource needs to follow the same locking protocol that a PATCH request requires.

About master_enable and sender_id

Hello.

According to what I read here, a PATCHing of the following JSON:

{
  "master_enable": false,
  "transport_params": [
    {
      "multicast_ip": "233.252.2.1"
    }
  ],
  "sender_id": "02bcb69b-751e-4138-9ac9-829f14362e02"
}

MUST be rejected, because "master_enable" (subscription active) cannot be false when "sender_id" is not null, am I correct?

Thanks.

Should server set sender_id to null when client does a patch of the staged with just an SDP?

When the nmos-explorer (version 1.1.1) is used to Paste an SDP into a receiver, the staged parameters just get a transport file. Should the IS-05 server set the sender_id in the staged parameters to null when this is done? Or should the IS-05 server count on the client to explicitly include a null sender_id?

In https://raw.githubusercontent.com/AMWA-TV/nmos-device-connection-management/v1.0.x/APIs/schemas/v1.0-receiver-stage-schema.json the description for sender_id indicates that the sender_id should be null if the receiver has not been configured to receive anything or if it is receiving from a non-NMOS sender. When just an SDP file is supplied, it isn't clear that the SDP file is associated with any NMOS sender so null might be appropriate. On the other hand, perhaps the client is supposed to know what is going on and explicitly set sender_id to null.

Must/should/may a receiver's "transport_file" be stale?

The Connection API receiver /staged spec is clear that "transport_params" should be updated to reflect the contents of a PATCHed "transport_file" (if not overwritten by "transport_params" in the same request).

I have been assuming the reverse is never the case, i.e. the contents of the "transport_file" will be as most recently PATCHed.

However, another possibility would be for the most recently PATCHed "transport_file" to be updated to reflect any "transport_params" in the same and subsequent requests. Is that required? Is it prohibited?

Thoughts? @simonrankine, @simonlo-sony, @billt-hlit

Multi-client operation requirements and what to do about in-flight immediate activations?

Background

The documentation describes behaviour for Multi-Client Operation. The spec clearly states implementation requirements on activation responses for PATCH vs. GET /staged.

Assume an underlying implementation where activation may take an appreciable length of time.

What to do about in-flight immediate activations?

While an immediate activation is in flight, if it concurrently receives a PATCH request on the same resource, an implementation could (thought-experimentally):
(a) block the new request until the in-flight activation is complete (or the API/app is shutting down)
(b) process the new request as if the in-flight one is complete (queue it up somehow?)
(c) return an error (probably has to be 500, not 423, because the spec doesn't allow for an immediate activation to be cancelled, even if the underlying implementation did)

Similarly, a concurrent GET request could:
(a) block
(b) return (i) prior state, (ii) future state (lie), or (iii) an in-flight state (e.g. with mode set to "activate_immediate", but that's explicitly prohibited by the spec)
(c) error (500)

Is the intention of the spec that a PATCH should (a) block, and a GET should (b)(i) return prior state or (a) also block?

If that's so, while a client must obviously expect that an immediate activation takes as long as it takes, it wasn't obvious to me that either a scheduled activation or even a staging-only request could also have to block for a pending immediate activation.

Thoughts? @simonrankine, @simonlo-sony, @billt-hlit

Potential requirement for additional MQTT parameters

As noted in AMWA-TV/is-07#54, it may be necessary to indicate a protocol version (including versions supported via constraints), and any need for a 'secure' parameter should be considered. These could be handled later via 'ext_' parameters but would be better sorted now before finalising this version of the spec.

Consider whether new transport types can be supported without a version bump

As of v1.1-dev, new transport types have been added (websocket/mqtt), but a version bump is required in order to add any further new ones. This is the safest route, but it may be useful to be able to avoid version bumps for any future new transport types. There are of course a number of trade-offs, including:

  • If we supported new transports without version changes, the transport constraints and other schemas would need to be documented elsewhere to avoid the spec itself changing. This may make testing harder, and it may be harder to keep them stable / avoid accidental breaking changes.
  • With transport schemas held elsewhere, they would likely need to be versioned independently of the core spec. This helps with flexibility, but increases complexity for servers, clients and end users. Clients in particular may encounter several matching IS-05 versions but be unable to control all of them due to differing transport parameter schema versions.

This topic can be discussed at a later date if it is deemed important.

IS-05 v1.1-dev "ext_" patternProperties regex is wrong

Unless I misunderstood, all 5 instances of the "ext_" patternProperties introduced into v1.1-dev by 0e159ae have spaces in where they shouldn't.

"^ext_[a-z A-Z 0-9 _]+$" needs condensing to "^ext_[a-zA-Z0-9_]+$"

(Aside: we need a note in 'NMOS Core' giving guidance about the character classes used for identifiers/tokens (e.g. how to decide when introducing a new identifier of some kind, whether or not they should allow numbers, hyphens, underscores, upper vs. lowercase, etc.)

Use PATCH with application/merge-patch+json

Wouldn't it be more in the spirit of PATCH as described in RFC 5789 to use a specific patch document type such as application/merge-patch+json (RFC 7396) instead of application/json?

Backwards compatibility could be achieved by allowing the old type as a deprecated alternative.

Multiple source addresses

At present the spec currently makes no allowance for multiple sources addresses for source specific multicast. For example this may be useful to allow a single receiver to receiver both legs of a SMPTE 2022-7 stream.

2022-7 corner cases

We have trouble understanding how Nodes and Clients should behave in some 2022-7 "corner cases".

There was a discussion (#68) about a mismatch of the amount of legs in a PATCH request. The conclusion of that discussion was, a PATCH must always contain the exact amount of legs as announced on the /constraints endpoint.

This means, it is not directly possible to PATCH the transport_params of a 1-legged sender onto a 2-legged receiver without modification. The Client must manually add a second empty object to the transport_params to make it a valid request.

On the other hand, in the 4.1. Behaviour - RTP Transport Type document the following is stated:

Where a Receiver supports SMPTE 2022-7 but is required to receive a non-SMPTE 2022-7 stream, only the first set of transport parameters should be used. rtp_enabled in the second set of parameters must be set to false and transport parameters in the SDP file should be mapped onto that first set of parameters in the array.

Where a Receiver does not support SMPTE 2022-7 but receives a SMPTE 2022-7 transport file containing two sets of transport parameters it is recommended that it parses the first set of transport parameters found in the file and joins the stream as if it were a non-SMPTE 2022-7 stream. This ensures compatibility with Senders which do not support operation in a non-SMPTE 2022-7 mode.

The quoted text makes the assumption, that for example a 2-legged receiver receives a PATCH with only 1 leg, therefore he should just rtp_enable=false his second, unused leg. The other case is, that a receiver receives a PATCH containing transport_params for 2 legs, but only supports 1, therefore he should neglect the second leg.

Regarding the discussion in #68 and it's changes on the spec, the conditions described in the quote are invalid.

Where should the logic reside?
Should the Client take care of the different amount of legs or should the Node act intelligent and take care of this mismatch.

Best what I can read from the current intersection of the specs & the schema is the following:

  • a PATCH containing a different amount of legs compared to the 'to-be-patched' transceiver should be discarded by the Node
  • the Client should take care of differences in these cases by adding empty objects ({}) in the transport_params array.*

(*) In some cases even more: if we want to PATCH a one-legged sender onto a receiver who currently has 2 active legs, the Client must even include a rtp_enabled=false in the missing leg to prevent having a receiver in a complete messed up state.

Meaning of "default" in the RTP parameters schemas

Similar to #37, I think the intended semantics of the several instances of "default", and especially, "default": "auto" in the JSON Schemas should be clarified, or those defaults removed.

Presumably a PATCH /staged request that doesn't include a particular property, means "don't change the value of that property", not "consider I specified the schema default".

I suspect the schema defaults are intended to convey that a newly powered-on device MAY, SHOULD or MUST (I don't know which!) logically start with those defaults.

Of course, the implementer still needs to take care about preparing a response to GET /active, when the schema default is "auto", since the GET requests on /active are specified as follows:

On activation all instances of "auto" should be resolved into the actual values that will be used

Perhaps the word should in that sentence ought to be MUST? Or is returning "auto" in responses to the /active endpoint actually allowed?

Behaviour of "master_enable" in /single/receivers/{receiverId}/staged

In APIs/schemas/v1.0-receiver-stage-schema.json we find:

https://github.com/AMWA-TV/nmos-device-connection-management/blob/bef1bc18c625f5f47a3b07b64b029fdc13cacc38/APIs/schemas/v1.0-receiver-stage-schema.json#L16-L20

What does that default value mean when making a PATCH request? If "master_enable" is omitted by the client, should the receiver be enabled? Or is this a copy-and-paste mistake from the response schema?

The equivalent sender stage schema does not have the same default.

[v1.1 review] Requests for transports not supported by this API version

Upgrade Path doc has this:

Where a transport type is added in a new version of the Connection Management API specification, earlier versioned APIs must not list any Senders or Receivers which make use of this new transport type.

I think we could align with the IS-04 Query API and Registration API, and use the HTTP 409 Conflict status code to distinguish this case from 404 Not Found.

As well as the /single endpoints, this would also apply if an id of a resource with an unsupported transport was used in a PATCH request on the /bulk endpoints.

Extensibility of "transport_params" and /constraints to other transport types

The schema for senders’ and receivers’ parameters (for /staged, /active, etc.) breaks out the sub-schemas for their “transport_params”, so in each case we have a separate schema for RTP vs. (the placeholder) for DASH. Four schemas in total.

For both senders and receivers, the schema for RTP parameters requires that the value is an array, to support multi-leg ST 2022-7.

First question – I'm now wondering whether we envisage that other transport types might not have a top-level array, and just be a single object, rather than always an array of one-two(/more)?

Next, look at senders’ and receivers’ /constraints endpoints. Here, if I understand correctly, we’ve currently got a single schema and not separate ones for senders and receivers on the one hand, or separate ones for RTP and other transport types (e.g. even a placeholder for DASH) on the other.

A single schema would make complete sense if it could work with any transport type, e.g. didn’t mention actual property names. However, at the moment - in order to work for both the senders’ and receivers’ /constraints endpoints - we ended up mentioning the union of the RTP parameters for both.

Second question – I'm wondering how we will extend this to support other transport types?

(And the relevance of the first question here is that the /constraints endpoint schema is currently a top-level array, matching the RTP "transport_params", but will that always be the case for other transport types?)

Any thoughts?

SDP files without 'source-filter'

As far as I can tell, none of the relevant SMPTE ST or IETF RFC require the a=source-filter: line.
JT-NM TR-1001-1:2018 Section 10.3 has:

Media Nodes shall support IGMP V3, and shall use the source-specific method if the source address information is provided in the SDP.
[...]
Senders should include source address information in the SDP.

That being the case, how should a Receiver react to PATCH /staged with an SDP file not containing the 'source-filter' information, in both the case of a single-legged, and ST 2022-7 dual-legged, Receiver?

Not use source-specific join ("source_ip": null?)
Use SDP Origin (o=) info?
Something else?

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.