eclipse-aaspe / server Goto Github PK
View Code? Open in Web Editor NEWC# based server for AASX packages
License: Other
C# based server for AASX packages
License: Other
Hi,
while testing the download feature of the REST server part, I figured the aasx file is somehow rebuilt for download. At least the xml part is rewritten.
This will fail, if a signed aasx file is downloaded, since the signature verification of the downloaded file will most likely fail (except for the case the rebuilt xml matches exactly the original one). Also, it simply seems odd the downloaded file does not match the original one.
I suggest, the download endpoint should just take the aasx file from the input folder and send it to the client as is.
Currently the API endpoint PUT /shells/{aasIdentifier}/asset-information/thumbnail
is missing in AssetAdministrationShellRepository
controller in the latest release.
Hi everyone
There seem to be a problem when it comes to refreshing the content onthe Blazor GUI. When new models are added to "/AasxServerBlazor/aasxs/" , they do not show up automatically as expected and the container must be restarted in order for that to happen.
I have tried with both volumes and bind-mounts to no avail
Hello,
When I copy AASX packages into the aasxs directory of docker container I have to restart the docker container to see the packages listed on the
http://localhost:51310/server/listaas
Is this normal behavior or a bug?
When I try to PUT an Aasx File to replace the Example Motor, I got this.
I'm confused about what form the http body should be?
Thank you.
Error Message:
The input is not a valid Base-64 string as it contains a non-base 64 character, more than two padding characters, or an illegal character among the padding characters.
I think it whould be nice to have a aasx archive validate-against-specification feature as implemented in [1]. I propose one of the following implementations, or maybe a combination, the the user can switch strict/loose by command line option or similar:
/// <summary>
/// validation class, contains file and valdation status information as well as an optional list of errors found in the file
/// </summary>
public class ValidationStatus
{
/// <summary>
/// the numeric id of the aasx file
/// </summary>
[Required]
public long Id { get; set; }
/// <summary>
/// the validation status of the given aasx file
/// </summary>
[Required]
public bool Valid { get; set; }
/// <summary>
/// the list of errors found in the aasx file
/// </summary>
public IList<ValidationError>? Errors { get; set; } = null;
}
/// <summary>
/// validation error class, contains error information for a specific error found in the parsed aasx file
/// </summary>
public class ValidationError
{
/// <summary>
/// the line containing the error
/// </summary>
[Required]
public long Line { get; set; }
/// <summary>
/// the exact error found in that line
/// </summary>
[Required]
public ErrorType Type { get; set; }
/// <summary>
/// a meaningfull description of the error, should be human-readable
/// </summary>
[Required]
public string Description { get; set; }
/// <summary>
/// optional debugging message (for development purposes)
/// </summary>
public String? DebugMessage { get; set; }
}
/// <summary>
/// enum containing all implemented error types, to the error output can be machine-readable
/// </summary>
public enum ErrorType
{
/// <summary>
/// thrown when a (sub) element is missing
/// </summary>
MissingElement,
/// <summary>
/// thrown when a (sub) element is unexcpeted
/// </summary>
ExtraElement,
/// <summary>
/// thrown when a value of an element cannot be parsed
/// </summary>
ParseError,
/// <summary>
/// thrown when an element in the file is unspecified
/// </summary>
UnknownElement
// to be continued
}
How do I set the Request Body for POST /shell-descriptors?
I would like a concrete example. I don't know the relationship with the existing Example_AAS_ServoDCMotor_21.aasx file.
Does anyone know?
I don't understand as there is no detailed description in IDTA-01002-3-0_SpecificationAssetAdministrationShell_Part2_API.pdf.
I would like to know more about AssetAdministrationShellRegistryAPIApi.
It is possible to add some documentation on the REST API provided with the server if present?
Some minimal documentation can be founded on the previous repository but not detailed enough to be really useful.
I want to add a SubmodelElement to my AAS. I first tried your example to add the new Property RotationSpeedNEW:
PUT
http://localhost:51310/aas/ExampleMotor/submodels/OperationalData/elements
Payload:
{
"value": "1234",
"valueId": null,
"semanticId": {
"keys": [
{
"type": "ConceptDescription",
"local": true,
"value": "http://customer.com/cd//1/1/18EBD56F6B43D895",
"index": 0,
"idType": "IRI"
}
]
},
"constraints": [],
"hasDataSpecification": [],
"idShort": "RotationSpeedNEW",
"category": "VARIABLE",
"modelType": {
"name": "Property"
},
"valueType": {
"dataObjectType": {
"name": "integer"
}
}
}
This all worked fine and the Property was added to the AAS. But when looking in detail in the new entry it looks like the valueType is not correctly stored in the AAS because it is empty. This is my result of the
GET
http://localhost:51310/aas/ExampleMotor/submodels/OperationalData/elements/RotationSpeedNEW
Result:
{
"elem": {
"value": "1234",
"valueId": null,
"semanticId": {
"keys": [
{
"type": "ConceptDescription",
"local": true,
"value": "http://customer.com/cd//1/1/18EBD56F6B43D895",
"index": 0,
"idType": "IRI"
}
]
},
"constraints": [],
"hasDataSpecification": [],
"idShort": "RotationSpeedNEW",
"category": "VARIABLE",
"modelType": {
"name": "Property"
},
"valueType": {
"dataObjectType": {
"name": ""
}
},
"kind": "Instance",
"descriptions": null
},
There you can see that valueType.dataObjectType.name is empty but in the payload of the PUT-Request it was defined as integer.
Can anyone please help me why this is happening?
Branch: masterV3
When using the REST API to upload attachments or thumbnails into an existing AAS this does not update the underlying package.
We always need to download the package and afterwards upload it again (using the PUT /packages/{packageID}
endpoint) to make the changes permanent.
Is this the intendend behaviour or should adding files via REST API automatically update the stored AASX package?
Edit:
There is a bug when editing an AASX with the PUT package endpoint after a change was done to the original AASX file.
I think a proper fix should be changing this line
into this
var originalFile = _envFileNames[packageIndex];
Hey there,
For the use of the AASX-server in the SDM4FZI-project, I want to deploy an AASX-server in a Kubernetes cluster and use keycloak for authentication. However, I am wondering how to configure the server so that I can use keycloak.
Is there any documentation or guide on how to achieve this?
Would be great, if you could help me out.
Hello, is there a way to make the values in the OPC Server writeable? Currently it is read-only. Another nice feature would be that the OPC Server updates when changes through the REST API are made. For example, if I delete a submodel with the REST API, it could also be deleted in the OPC Server.
Description
Branch: masterV3
Serialization and deserialization of type AasCore.Aas3_0_RC02.LangString
are done in a different way.
Example
When creating an AAS or submodel and setting a language string, for instance on the property displayName or description it is necessary to use an JSON array, containing AasCore.Aas3_0_RC02.LangString
objects.
"description": [
{
"language": "en",
"text": "English Text "
}
]
When querying data from the server, the format is different. There is another object langStrings
introduced, containing the langugage string array. This was also the case in previous versions.
"description": {
"langStrings": [
{
"language": "en",
"text": "English Text "
}
]
},
At least on point should be changed because the latest Swagger API definition also does not contain the extra langStrings
object. Handling serialization and deserialization would make things unnecessarily complex.
In the latest release there is a typo in the route of the endpoint that uploads attachments to submodel elements in SubmodelRepositoryAPI
controller.
It should be submodels/{submodelId}/submodel-elements/{idShortPath}/attachment
but currently it is submodels/{submodelId}/submodelelements/{idShortPath}/attachment
which is not conformant with the standard.
I would like to ask how often is docker images are refreshed. Because we have found out that there is a big discrepancy between docker latest image and main source code. When i tried to create a submodel using docker image running on my mac, it was working fine but exact the same client code, I have executed downloading the latest main source code and running in VS 2022, it threw an exception.
So obviously docker image was not up-to-date.
Branch: masterV3
At the moment it is not possible to create an operation that does not have inputs our outputs.
This can be fixed by adding a null check just before the foreach
loops in
and
and
It might be worth checking out something like https://github.com/commandlineparser/commandline or similar to simplify input parsing and keep the project at a maintainable size.
Just a suggestion.
If the submodel Bill of material is created and populated with Self managed Entities the relation between the Element in the Bill of material Submodel and the referred AAS should be managed by the server.
In this way by clicking on the reference the corresponding AAS should open and the navigation between them for the user is simplified.
I cannot start the server with the demo configuration (startFordemo.bat).
This is the output of the executable
AasxServerCore.exe --rest --no-security --data-path aasxs
Serving the AASXs from: aasxs
Security 1 Startup - Server
Security 1.1 Load X509 Root Certificates into X509 Store Root
Loading aasxs\Example_AAS_ServoDCMotor_21.aasx...
Please wait for the servers to start...
Connect to REST by: localhost:51310
http://localhost:51310/
REST Server started.
Test: ../proxy.dat
Servers successfully started. Press Ctrl-C to exit...
localhost server output in browser
Route Not Found For GET /
<br>
at Grapevine.Server.Router.Route(IHttpContext context, IList`1 routing)
at Grapevine.Server.Router.Route(Object state)
Closed this issue as I forgot to add the endpoint of the API as mentioned in the readme
Hi everyone,
there seemts to be an issue when both REST- and OPC UA-server are started serving an AAS including submodels.
When, for example, the value of a property is editted via REST-API, the corresponding OPC UA node seems not to take over the new value.
Could you please have a look at it?
Might there be something similar to Blazor's Program.signalNewData() function?
Regards, Magnus
Hi everyone,
when I start an attached container with:
docker run --name assx-server --rm adminshellio/aasx-server-blazor-for-demo
logs tell me I can stop the server with ctrl+c.
And it's common for containers to react to these signals, e.g. ctrl+x
PROBLEM: But the container doesn't react to any input and therefore cannot be stopped directly.
I always need to stop the container on another shell with docker stop assx-server
The same thing happens when I start the container with the -it
flags.
Maybe this answer can also be helpful. https://stackoverflow.com/a/41099052
All devices are connected to the same network (192.168.1.xxx).
When I execute AASX-SERVER on my laptop (IP: 192.168.1.104)
~/AasxServerCore.2022-07-25.alpha\AasxServerCore>AasxServerCore.exe --rest --opc --mqtt --edit --no-security --data-path aasxs
Serving the AASXs from: aasxs
Security 1 Startup - Server
Security 1.1 Load X509 Root Certificates into X509 Store Root
Connect to OPC UA by: opc.tcp://0.0.0.0:51210/UA/SampleServer
Loading aasxs\15_Siemens.aasx...
Loading aasxs\Example_AAS_ServoDCMotor_21.aasx...
Loading aasxs\Wika_PSD4.aasx...
Please wait for the servers to start...
Connect to REST by: localhost:51310
http://localhost:51310/
REST Server started.
MQTT Publisher started.
OPC UA Server started..
Servers succesfully started. Press Ctrl-C to exit...
I can access the server normally at the address http://localhost:51310/server/listaas in the same laptop (IP: 192.168.1.104) that I run the server.
~/ curl http://localhost:51310/server/listaas
{
"aaslist": [
"0 : Siemens_S7_CPU1515 : [IRI] www.company.com/demo/aas/1234554842136874684321 : aasxs\\15_Siemens.aasx",
"1 : ExampleMotor : [IRI] http://customer.com/aas/9175_7013_7091_9168 : aasxs\\Example_AAS_ServoDCMotor_21.aasx",
"2 : Wika_PSD4_1 : [IRI] https://example.com/ids/ass/0330_9101_5032_3395 :
aasxs\\Wika_PSD4.aasx"
]
}
But when I try to access another computer or device like Raspberry PI (IP: 192.168.1.114), the server created in the laptop (IP: 192.168.1.104) does not respond.
pi@raspberrypi:~ $ curl http://192.168.1.104:51310/server/listaas
... (does not respond or do not return anything)
I also tried to use the --host
option (IP: 192.168.1.104) and was unsuccessful either.
I surrounded other aasx-server versions such as aasxservercore.2022-01-13.alpha and the same problem persists.
The same type of problem happens when trying to access the AASX-SERVER through the OPC UA, being possible only connect and view in the same machine (OPC.TCP: // localhost: 51210/UA/SampleServer), if I try to access another device,and take a search in the same option it does not even find the correct IP of the laptop (OPC.TCP: //192.168.1.104: 51210/UA/SampleServer) on the OPC UA client.
For the industrial use-case the type AAS needs a mandatory version information in both the aasx file and in the server responses.
i.e If a file download is generated from the AASX server, the file content needs to be exact the same as the published file.
This is currently not true in branch erichb-masterv3.
Is there a specific version information defined for the aasx file and the AAS itself?
In general there aasx-server source code has problem with the sub list when they are null, it crashes or silently failing. For example, we have found out that when submodels list is "null" for created shell it crashes. see the image below
but then when you create an empty list, Verify, you get error as below
"Invariant violated:
Statements must be either not set or have at least one item."
var verifyResultErrors = Verification.Verify(submodel);
So it makes verification not useful. I believe here verify method doest correct job while aasx-server code should make a null check in general.
Currently only SubmodelElementCollections and Operation can be traversed in the HTTP API, but the Entity statements should also be able to traverse easily in the API.
I will link an pull request with an implementation of this feature
Hello, it is possible to build up a connection from the Package Explorer to the AASX Server to add further AAS into the designated directory. Which kind of connection does work for this? Is there a documentation available?
Thanks
When using the binaries I have not been able to exit the application with CTRL-C. I rather have to close the terminal. Is this a bug or is there a way to know why this is not working on my end.
regards
I am trying to check how to update properties via the HTTP/REST API but I have not been able to do it properly.
I tried the following PUT request to update the OperationalData
submodel property RotationSpeed
but it did not work.
http://localhost:51310/aas/ExampleMotor/submodels/OperationalData/elements/RotationSpeed
{
"value": "1234"
}
Matching SubmodelElement in Submodel OperationalData is not suitable to add childs.
OPC Server start failed on both windows and blazor versions
Error:
Application startup exception: System.MissingMethodException: Method not found: 'Void Microsoft.AspNetCore.Server.Kestrel.Core.ListenOptions.set_NoDelay(Boolean)'.
at Opc.Ua.Bindings.UaHttpsChannelListener.<>c__DisplayClass7_0.<Start>b__1(ListenOptions listenOptions)
at Microsoft.AspNetCore.Server.Kestrel.Core.KestrelServerOptions.Listen(IPEndPoint endPoint, Action`1 configure)
at Microsoft.AspNetCore.Server.Kestrel.Core.KestrelServerOptions.Listen(IPAddress address, Int32 port, Action`1 configure)
at Opc.Ua.Bindings.UaHttpsChannelListener.<>c__DisplayClass7_0.<Start>b__0(KestrelServerOptions options)
at Microsoft.Extensions.Options.ConfigureNamedOptions`1.Configure(String name, TOptions options)
at Microsoft.Extensions.Options.OptionsFactory`1.Create(String name)
at Microsoft.Extensions.Options.OptionsManager`1.<>c__DisplayClass5_0.<Get>b__0()
at System.Lazy`1.ViaFactory(LazyThreadSafetyMode mode)
at System.Lazy`1.ExecutionAndPublication(LazyHelper executionAndPublication, Boolean useDefaultConstructor)
at System.Lazy`1.CreateValue()
at System.Lazy`1.get_Value()
at Microsoft.Extensions.Options.OptionsCache`1.GetOrAdd(String name, Func`1 createOptions)
at Microsoft.Extensions.Options.OptionsManager`1.Get(String name)
at Microsoft.Extensions.Options.OptionsManager`1.get_Value()
at Microsoft.AspNetCore.Server.Kestrel.Core.KestrelServer.CreateServiceContext(IOptions`1 options, ILoggerFactory loggerFactory)
at Microsoft.AspNetCore.Server.Kestrel.Core.KestrelServer..ctor(IOptions`1 options, IConnectionListenerFactory transportFactory, ILoggerFactory loggerFactory)
at System.RuntimeMethodHandle.InvokeMethod(Object target, Object[] arguments, Signature sig, Boolean constructor, Boolean wrapExceptions)
at System.Reflection.RuntimeConstructorInfo.Invoke(BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitConstructor(ConstructorCallSite constructorCallSite, RuntimeResolverContext context)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSiteMain(ServiceCallSite callSite, TArgument argument)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitCache(ServiceCallSite callSite, RuntimeResolverContext context, ServiceProviderEngineScope serviceProviderEngine, RuntimeResolverLock lockType)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitRootCache(ServiceCallSite singletonCallSite, RuntimeResolverContext context)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSite(ServiceCallSite callSite, TArgument argument)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.Resolve(ServiceCallSite callSite, ServiceProviderEngineScope scope)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.DynamicServiceProviderEngine.<>c__DisplayClass1_0.<RealizeService>b__0(ServiceProviderEngineScope scope)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngine.GetService(Type serviceType, ServiceProviderEngineScope serviceProviderEngineScope)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngine.GetService(Type serviceType)
at Microsoft.Extensions.DependencyInjection.ServiceProvider.GetService(Type serviceType)
at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(IServiceProvider provider, Type serviceType)
at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService[T](IServiceProvider provider)
at Microsoft.AspNetCore.Hosting.WebHost.EnsureServer()
at Microsoft.AspNetCore.Hosting.WebHost.BuildApplication()
My .net env:
Host:
Version: 6.0.9
Architecture: x86
Commit: 163a63591c
.NET SDKs installed:
No SDKs were found.
.NET runtimes installed:
Microsoft.AspNetCore.App 3.1.29 [C:\Program Files (x86)\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 6.0.9 [C:\Program Files (x86)\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.NETCore.App 3.1.29 [C:\Program Files (x86)\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 5.0.17 [C:\Program Files (x86)\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 6.0.9 [C:\Program Files (x86)\dotnet\shared\Microsoft.NETCore.App]
Microsoft.WindowsDesktop.App 5.0.17 [C:\Program Files (x86)\dotnet\shared\Microsoft.WindowsDesktop.App]
Tried to use Beckhoff OPC UA Client connect to port 51310 but failed:
Error while loading endpoints - BadSecureChannelClosed
When trying to download a non-existing file from an archive the REST server part throws an exception and sends the exception message with HTTP status code 200 to the client.
I suggest, the REST server should send a 404 HTTP status code. The exception message should be logged, not sent to the client. Maybe it would be a nice idea to to have a configurabe error json object to be send to the client in case of an error; the object could include the exception message for development purposes or internal usage.
The missing/broken error handling seems to be related to #58
Is it possible to use AAS Events to propagate the updated value of a property from one instance of the Package Explorer to another, via an AAS Server.
To clarify the two Package Explorers are connected via REST to the same server and viewing the same AAS, a change is made to a property in one Package Explorer, saved back to the server, should the second Package Explorer update the property?
From the specification it looks as if it should be possible, but when I tried it, it did not work.
I'm running the latest Blazor-Release as a docker container.
The gui interface seems to be working.
When I try the following:
I get the following response:
{
"messages": [
{
"code": "InternalServerError",
"correlationId": null,
"messageType": "Error",
"text": "Object reference not set to an instance of an object.",
"timestamp": "10/13/2023 07:10:10"
}
]
}
Does anyone have an idea if I'm doing anything wrong?
Describe the bug
Branch masterV3 provides a resource /shells/{aasIdentifier}/submodels
which should include the same query parameters as for /submodels
.
/shells/{aasIdentifier}/submodels
:
/submodels
:
At the moment it is not possible to request a specific submodel of a AAS by semanticID
or idShort
.
I read the README.md file and saw the API for this project. Is it possible to upload a package to the server via the API or can it only be done via the package explorer?
Please correct me if I am wrong as I am new to the Asset administration shell.
I want to use OPC UA as default connectivity to the Asset Administration Shells. I need to add nodes while the Application is running.
Right now I'm not sure if I need to change the Server or Client Application. Since I want to add information from the Client it should be the client, but this could result in harming the structure of the AAS, proably there should be a Methode to add information to the AAS. and if the serialized data isn't correct or incomplete the server should denie the request.
Where should I try to add nodes to the server?
I would appreciate some other thoughts about this.
As shown below server crashes if the statements are null. I have tested using Demo Box samples from here http://www.admin-shell-io.com/samples/
Hello!
I'm trying to represent the "WebService" submodel for the scenario: "A device can offer multiple web services".
The AASX Package Explorer allows me to create many submodels with the same IdShort (WebService), but the AASX-Server's API only returns the first record:
/aas/{aas-identifier}/submodels/{submodel-identifier}
Is it an issue or I'm not in the right direction? Please help
In AasxHttpContextHelper.cs the FindAAS
function is used in several places without checking if the return object is null.
For example:
var findAasReturn = this.FindAAS(aasid, context.Request.QueryString, context.Request.RawUrl);
if (findAasReturn.aas == null)
{
context.Response.SendResponse(HttpStatusCode.NotFound, $"No AAS with idShort '{aasid}' found.");
return;
}
If the AAS cannot be found, the FindAAS function either returns null
directly or a FindAasReturn.aas
which is null.
Due to the missing null check the REST server breaks:
curl -v http://localhost:51310/aas/123
Output:
> GET /aas/123 HTTP/1.1
> Host: localhost:51310
> User-Agent: curl/7.68.0
> Accept: */*
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 Ok
< Server: Grapevine/4.1.2.0
< Date: Mon, 08 Feb 2021 21:37:14 GMT
< Content-Length: 703
<
Exception has been thrown by the target of an invocation.
<br>
at System.RuntimeMethodHandle.InvokeMethod(Object target, Object[] arguments, Signature sig, Boolean constructor, Boolean wrapExceptions)
at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
at System.Reflection.MethodBase.Invoke(Object obj, Object[] parameters)
at Grapevine.Server.Route.<>c__DisplayClass42_0.<ConvertMethodToFunc>b__1(IHttpContext context)
at Grapevine.Server.Route.Invoke(IHttpContext context)
at Grapevine.Server.Router.Route(IHttpContext context, IList`1 routing)
* Connection #0 to host localhost left intact
at Grapevine.Server.Router.Route(Object state)
https://learn.microsoft.com/en-us/dotnet/core/install/linux-scripted-manual
Could you support me with dotnet version 6 or 7?
thx
I can not find any information about the usage of the mqtt publisher, like topic and subsriber information. Please provide some documentation.
I created my AASX server(OPC UA and rest) with two AAS and i can succesfully connect to it from URL, but when I try to connect from AASX Package explorer connecting HTTP/REST repository with the URL http://localhost:51310?asp.net or http://localhost:51310 i receive this error:
I tried to connect by the connect via rest option but i obtain another error:
refers to #84
"dataObjectType" is not specified but somehow implemented in AASX Server
Hi,
I'm following your description in the README.md how to start the Blazor server, using:
docker run -p 51000:51310 -p 51001:5001 adminshellio/aasx-server-blazor-for-demo
The REST server is working, but the blazor Web UI is not working.
In the corresponding Dockerfile, the exposed ports are 51310 and 51210.
Can you please check and give me some advice how to continue?
Best regards,
Emil
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.