Giter VIP home page Giter VIP logo

pacdef's Introduction

check

pacdef

multi-backend declarative package manager for Linux

Installation

Arch Linux

pacdef is available in the AUR as stable release or development version or binary version.

binaries for other Linux versions

For every release since 1.5.0 you can download binaries for some other Linux versions. Check out the assets for the latest release.

from source

Install it from crates.io using this command.

$ cargo install [-F <backend>[,...]] pacdef

See below ("supported backends") for the feature flags you will need for your distribution.

shell completion

For Arch Linux, zsh completion will work automatically when you install pacdef from the AUR packages. For other distributions you must copy the _completion.zsh file to the right folder manually and rename it to _pacdef.

Use-case

pacdef allows the user to have consistent packages among multiple Linux machines and different backends by managing packages in group files. The idea is that (1) any package in the group files ("managed packages") will be installed explicitly, and (2) explicitly installed packages not found in any of the group files ("unmanaged packages") will be removed. The group files are maintained outside of pacdef by any VCS, like git.

If you work with multiple Linux machines and have asked yourself "Why do I have the program that I use every day on my other machine not installed here?", then pacdef is the tool for you.

Of groups, sections, and packages

pacdef manages multiple package groups (group files) that, e.g., may be tied to a specific use-case. Each group has one or more section(s) which correspond to a specific backend, like your system's package manager (pacman, apt, ...), or your programming languages package manger (cargo, pip, ...). Each section contains one or more packages that can be installed respective package manager.

This image illustrates the relationship.

       1   n       1   n         1   n      
pacdef ----> group ----> section ----> package 

Example

Let's assume you have the following group files.

base:

[arch]
paru
zsh

[rust]
pacdef
topgrade

development:

[arch]
rustup
rust-analyzer

[rust]
cargo-tree
flamegraph

Pacdef will make sure you have the following packages installed for each package manager:

  • Arch (pacman, AUR helpers): paru, zsh, rustup, rust-analyzer
  • Rust (cargo): pacdef, topgrade, cargo-tree, flamegraph

Note that the name of the section corresponds to the ecosystem it relates to, rather than the package manager it uses.

Supported backends

At the moment, supported backends are the following. Pull requests for additional backends are welcome!

Application Package Manager Section feature flag Notes
Arch Linux pacman [arch] arch includes pacman-wrapping AUR helpers (configurable)
Debian apt [debian] debian minimum supported apt-version 2.0.2 (see upstream)
Fedora Linux dnf [fedora] built-in
Flatpak flatpak [flatpak] built-in can manage either system-wide or per-user installation (configurable)
Python pip [python] built-in
Rust cargo [rust] built-in
Rustup rustup [rustup] built-in See the comments below about the syntax of the packages in the group file.
Void Linux xbps [void] built-in

Backends that have a feature flag require setting the respective flag for the build process. The appropriate system libraries and their header files must be present on the machine and be detectable by pkg-config. For backends that state "built-in", they are always supported during compile time. Any backend can be disabled during runtime (see below, "Configuration").

For example, to build pacdef with support for Debian Linux, you can run one of the two commands.

  • (recommended) cargo install -F debian pacdef, this downloads and builds it from https://crates.io
  • in a clone of this repository, cargo install --path . -F debian

Example

This tree shows my pacdef repository (not the pacdef config dir).

.
├── generic
│   ├── audio
│   ├── base
│   ├── desktop
│   ├── private
│   ├── rust
│   ├── wayland
│   ├── wireless
│   ├── work
│   └── xorg
├── hosts
│   ├── hostname_a
│   ├── hostname_b
│   └── hostname_c
└── pacdef.toml
  • The base group holds all packages I need unconditionally, and includes things like zfs, paru and neovim.
  • In xorg and wayland I have stored the respective graphic servers and DEs.
  • wireless contains tools like iwd and bluez-utils for machines with wireless interfaces.
  • Under hosts I have one file for each machine I use. The filenames match the corresponding hostname. The packages are specific to one machine only, like device drivers, or any programs I use exclusively on that machine.

Usage on different machines:

  • home server: base private hostname_a
  • private PC: audio base desktop private rust wayland hostname_b
  • work PC: base desktop rust work xorg hostname_c

Commands

Subcommand Description
group import [<path>...] create a symlink to the specified group file(s) in your groups folder
group export [args] <group> ... export (move) a non-symlink group and re-import it as symlink
group list list names of all groups
group new [-e] [<group>...] create new groups, use -e to edit them immediately after creation
group remove [<group>...] remove a previously imported group
group show [<group>...] show contents of a group
package clean [--noconfirm] remove all unmanaged packages
package review for each unmanaged package interactively decide what to do
package search <regex> search for managed packages that match the search string
package sync [--noconfirm] install managed packages
package unmanaged show all unmanaged packages
version show version information, supported backends

Aliases

Most subcommands have aliases. For example, instead of pacdef package sync you can write pacdef p sy, and pacdef group show would become pacdef g s.

Use --help or the zsh completion to find the right aliases.

Configuration

On first execution, it will create an empty config file under $XDG_CONFIG_HOME/pacdef/pacdef.toml. The following key-value pairs can be set. The listed values are the defaults.

aur_helper = "paru"  # AUR helper to use on Arch Linux (paru, yay, ...)
aur_rm_args = []  # additional args to pass to AUR helper when removing packages (optional)
disabled_backends = []  # backends that pacdef should not manage, e.g. ["python"], this can reduce runtime if the package manager is notoriously slow (like pip)

warn_not_symlinks = true  # warn if a group file is not a symlink
flatpak_systemwide = true  # whether flatpak packages should be installed system-wide or per user
pip_binary = "pip"  # choose whether to use pipx instead of pip for python package management (see below, 'pitfalls while using pipx')

Group file syntax

Group files loosely follow the syntax for ini-files.

  1. Sections begin by their name in brackets.
  2. One package per line.
  3. Anything after a # is ignored.
  4. Empty lines are ignored.
  5. If a package exists in multiple repositories, the repo can be specified as prefix followed by a forward slash. The package manager must understand this notation.

Example:

[arch]
alacritty
firefox  # this comment is ignored
libreoffice-fresh
mycustomrepo/zsh-theme-powerlevel10k

[rust]
cargo-update
topgrade

Rustup

Rustup packages are managed quite differently. For referring to the syntax, have a look below. In contrast to other package managers, rustup handles package naming very differently. These packages are either of the form toolchain/<VERSION> or component/<VERSION>/<component>, where can be stable, nightly, or any explicit rust version. The <component> field has to be substituted with the name of the component you want installed.

Example:

[rustup]
component/stable/rust-analyzer
toolchain/stable
component/stable/cargo
component/stable/rust-src
component/stable/rustc
toolchain/1.70.0
component/1.70.0/cargo
component/1.70.0/clippy
component/1.70.0/rust-docs
component/1.70.0/rust-src
component/1.70.0/rust-std
component/1.70.0/rustc
component/1.70.0/rustfmt

Misc.

Automation

Pacdef is supported by topgrade.

Naming

pacdef combines the words "package" and "define".

minimum supported rust version (MSRV)

MSRV is 1.74 due to dependencies that require this specific version. Development is conducted against the latest stable version.

Pitfalls while using pipx

Some packages like mdformat-myst do not provide an executable themselves but rather act as a plugin to their dependency, which is mdformat in this case. Please install such packages explicitly by running pipx install <package-name> --include-deps.

pacdef's People

Contributors

arctic-penguin avatar book-reader avatar danbluhmhansen avatar innocentzero avatar mike-lloyd03 avatar ripytide avatar star-szr avatar steven-omaha avatar teackot avatar teewallz avatar thcrt avatar thechubbypanda avatar zaubentrucker 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

pacdef's Issues

Review Resume

Currently, as a first time user is working through the review process, pacdef stores the results of each decision in memory and then applies them at the end.

The recent addition of the apply option (#61) allows users to save and apply their progress at any point. But if the user is interrupted for any reason, their progress is lost and they have to start over.

A temp file could be created in the user's temp directory to store the results of each decision. Once the review is done, this file is consulted to execute each action as is currently done.

If the review process starts and this file exists, it should be validated against the currently installed package list and packages which have already been evaluated will be skipped, leaving the user to handle whichever packages remain.

There's probably a number of edge cases to handle here and things which could leave the temp file in an unusable state. So there's a lot to consider.

I'm happy to implement this. Let me know your thoughts

add flatpak support

I loved the idea of this tool, and I'd use it a lot, but the problem is that I depend on some flatpak packages.

Is it feasible / planned to add support for it?

Thanks

Binary AUR package

Building the package every install/update is very time consuming. Building centrally and shipping a pacdef-bin package would be ideal. I'm happy to maintain the AUR package, just need somewhere to get the binaries.

Option to suppress symlink warnings

Really nice utility you've created. Looking forward to the Rust rewrite mentioned in #13.

I use pacdef with chezmoi to sync my group definitions. Since chezmoi best practice isn't to use symlinks, I get lots of warnings. It would be nice to be able to suppress them. That's all 😁

Add support for rustup/npm/yarn etc?

Hi, it's me again. I was wondering just how many package managers have been considered to be eventually supported by the project before, and if you intend to add more to the list, I'm happy (and more importantly free atm) to add support for rustup, npm, yarn, and a few others.

I'd like to start with rustup, since it seems the most straightforward to me. Or are there any alternative suggestions?

Option to skip confirmation for sync/clean actions

First of all, great tool, i find it extremely useful.

My goal would be to use pacdef as base for a fully automated pipeline which installs or removes packages in a set of devices when a definition is updated in a vcs repository.

The only thing stopping me is the interactive confirmation prompt, would you consider adding an option to make it unattended?

Eventually i could give it a go and open a PR, but i wanted to ask before hand, also considering i saw you started working on a rust version, anyway, let me know.

Features propositions

Hello,

Thank you for this tool this is really great. While learning to use this I implemented a few additional features and you may be interested in merging some here.

Features:

  • Have description of packages show up as comments in unmanaged and show
    Basically, the output of unmanaged or show will print the package and its description in comments. Example:
alsa-firmware #  Firmware binaries for loader programs in alsa-tools and hotplug firmware loader
alsa-lib #  An alternative implementation of Linux sound support
alsa-oss #  OSS compatibility library
alsa-plugins #  Additional ALSA plugins
alsa-utils #  Advanced Linux Sound Architecture - Utilities

This is very useful IMHO to sort through the packages, some of them I don't remember what they do. My first reflex with pacdef was to do pacdef unmanaged > misc, import the group misc and begin sorting from there but with description this process was a lot easier.

  • multiprocessing when processing packages using python's multiprocessing library.
    The program is then a lot faster in particular when there are a lot of packages installed, and it is easily made parallel.

  • I also added an argument in the pacdef.conf that contains command-line arguments passed to AUR helper when removing. In particular, I used the --cascade argument to delete packages that were dependencies of the packages I deleted.

Tell me if any of these features is of interest and I can do a PR.

libalpm.so.13: cannot open shared object file

pacdef: error while loading shared libraries: libalpm.so.13: cannot open shared object file: No such file or directory

Since yesterday this is happening any time I want to run pacdef. Before that nothing like this would ever occur.

Add support for pipx?

Hello, is it possible to add support for pipx installation utility? It is the recommended method to install python executables that are not available in the default repositories or in AUR.

Thanks a lot!

Package updates

How about adding support for updates? This will also require a new switches constant and getter

panic in python.rs in version 1.4.0

When trying to run: pacdef p sy I get a panic:

thread 'main' panicked at /.../pacdef_core-1.4.0/src/backend/actual/python.rs:80:18:
Cannot use  for package management in python. Please use a valid package manager like pip or pipx.

It looks like the python binary is defaulting to an empty string instead of a valid value. I fixed the panic by putting:

pip_binary: 'pipx'

in my pacdef.yaml. However, I would have thought that it would have a reasonable default.

Single package is not recognized without newline

Describe the bug
When I create a group containing a single package, pacdef fails to detect said package if there not a newline at the end of the file.

Affected version
Output of pacdef version: pacdef, version: 0.8.0

Output of python --version: Python 3.10.7

Operating System
Arch Linux, x86_64

To Reproduce
Steps to reproduce the behavior:

  1. Create a file foo containing a single package bar. Ensure there is no newline at the end of the file.
  2. pacdef import foo
  3. pacdef sync does not prompt the user to install bar.

Expected behavior
pacdef prompts the user to install bar.

'pacdef package review' enhancement suggestions

A couple minor changes to pacdef package review would improve it a lot.

  1. Offer to save the group assignments on q quit. Currently all changes are lost until the entire list has been reviewed.
  2. Allow multiple space delimited group assignments at the group assignment prompt.

Some other changes would improve it even more.

  1. Allow going back to the previous package.
  2. Allow creation of new groups while reviewing (understand if this is out of scope).

(This one deserves its own issue, but I'm hesitant to spam your issue list. Let me know if you want a separate issue for it.) Finally, a function similar to pacdef package unmanaged that instead shows all explicitly installed packages along with which group(s) they're in; if unmanaged, show no group.

Hopefully that wasn't too much. It comes from a place of love. Your utility is incredibly useful and I'm excited to watch it continue to improve and grow.

update `zsh` completion

  • add completion for pacdef group export
  • Review that all subcommands are completed properly

[rustup] Update Readme

What's still missing is updating the README to let the users know about the new rustup backend. This should all fit nicely in this table: https://github.com/steven-omaha/pacdef?tab=readme-ov-file#supported-backends

@InnocentZero Could you please add a line in the table at the very bottom, and give a brief description in the Notes column about the difference in toolchain and component packages? It will probably make sense to just say "see comment below" and explain it in one short paragraph, because rustup is different than all other package managers we have supported so far.

Thank you.

Group dependencies

It would be really cool to have one list be dependent on another. Different files could also satisfy the same dependency. For instance, desktop could depend on audio as well as one of [plasma, gnome, sway] where sway is itself dependent on wayland.

[Feature request]: use $CARGO_HOME

In one sentence, what would the new feature allow the user to do?

Use the $CARGO_HOME environment variable for rust packages if set

Describe what problem this new feature would solve.

I use the $CARGO_HOME environment variable to override the default ~/.cargo directory, this variable is described here Cargo Book - Environment Variables. This causes pacdef to never find the .crates2.json file.

How should this feature in your opinion work?

Prioritize $CARGO_HOME with a fallback to $HOME/.cargo when looking for the .crates2.json file.

Would you be willing to implement this? We would support you through this process.

  • Yes, I would like to implement this.

Additional information

I already have a pull request ready that I can open if that's alright.

AUR installation does not include `pacdef_core`

Hi there!

I am trying to install pacdef through the AUR (specifically, paru), but it fails as pacdef_core is not included:

error: no matching package named `pacdef_core` found
location searched: registry `crates-io`
required by package `pacdef v1.3.0 (/home/philpax/.cache/paru/clone/pacdef/src/pacdef-1.3.0)`

Looking into it, this appears to be because the AUR pkgbuild downloads the pacdef crate from crates.io, which does not include crates/pacdef_core.

I'd suggest changing pacdef's Cargo.toml to point at a published version of pacdef_core; the publish process will only use the published version of the crate, which should allow you to develop and publish versions at the same time. (With the caveat that you'll need to use something like cargo release to publish all of the crates at the same time.)

aur_rm_args not parsing?

Either pacdef isn't parsing aur_rm_args correctly or I'm doing it wrong.

$ pacdef version
Error: unexpected error: loading config file

Caused by:
    0: parsing yaml config
    1: aur_rm_args: invalid type: string "-Yc", expected a sequence at line 2 column 14

pacdef.yaml:

aur_helper: yay
aur_rm_args: -Yc 
warn_not_symlinks: true
disabled_backends: []

EDIT:
Ok, looked more closely at the docs. aur_rm_args is an array. Changed to below and it's not giving the error anymore.

aur_helper: yay
aur_rm_args: ["-Yc"] 
warn_not_symlinks: true
disabled_backends: []

extra newline after assign to group

Unmanaged packages:
  mlocate
  tig
[...]

tig
assign to (g)roup, (d)elete, (s)kip, (i)nfo, (a)s dependency, (q)uit? g
 0: audio
 1: base
 2: desktop
 3: XXXXX
 4: private
 5: python
 6: rust
 7: ssd
 8: XXXXXXX
 9: wireless
10: work
11: xorg
Group or (c)ancel? 1


Will delete the following packages:
  mlocate

Will assign packages as follows:
  tig -> base

Declarative way of mapping groups to hosts

Hi,

Pacdef is applying a declarative approach to package management -- a method I prefer without the overhead of NixOs.

However to actually apply the configs to a machine in Pacdef, one needs to imperatively run 'import' to apply the config to a machine from my understanding, using a symlink as the way to link a group to a host. If these symlinks are lost, the desired state is lost. This would then need an imperative script overlayed on top of pacdef to create reproducible builds and ensure state.

EDIT: (Upon looking at this, pacdef group new test already outputs to config/pacdef/groups/, which creates a non-symlink already, breaking what seems to be the best practices the project is after - and making the current host use all newly created groups by default). What is the desired workflow, i.e. a basic 'test_run.sh)? Is it pacdef create -> cut files into git dir-> import/symlink back again? )

Is there a way to apply the groups to a host via the config, it to detect the current host (like Ansible) , i.e.

cat hosts/host1
[group1]
[group2]
[package2]

hosts/host2
[group2]
[group3]
[package1]

and enable the ability to run :

git clone <config>
# [No imports]
pacdef sync

I understand there is currently 'hosts' directory for host-specific packages, but if there are overlaps you'd have to duplicate package groups

Is this something that is already done, or this package has an appetite for if not present?

Thanks for the package, Love your work! : D

[Bug]: review apply only finishes backend / section

In one sentence, what did you try to achieve?

Finishing the review by pressing p for apply.

What did you expect to happen?

Hitting apply in pacdef package review finishes the review for all packages.

What happened?

It only finishes the review for the packages in the current backend / section.

How can we reproduce this?

  1. Have at least two unmanaged packages for one backend and at least one for a second backend.
  2. pacdef p r
  3. Delete the first package, hit apply on the second.
  4. pacdef prompts about the intention for the first package in the second backend.

Version of pacdef

pacdef, version: 1.4.2 (743c955)
supported backends:
  arch
  flatpak
  python
  rust
  rustup

Pacdef config

disabled_backends: ["python", "flatpak"]

What operating system and version are you encountering this issue on?

LSB Version:	n/a
Distributor ID:	Arch
Description:	Arch Linux
Release:	rolling
Codename:	n/a

Relevant log output

arch: acpi
assign to (g)roup, (d)elete, (s)kip, (i)nfo, (a)s dependency, a(p)ply, (q)uit? d
arch: cpupower
assign to (g)roup, (d)elete, (s)kip, (i)nfo, (a)s dependency, a(p)ply, (q)uit? p
rustup: toolchain/nightly
assign to (g)roup, (d)elete, (s)kip, (i)nfo, a(p)ply, (q)uit?

Additional information

cc @mike-lloyd03

fix inconsistent line spacing

Review

  • iterating over packages has no whitespace, makes it hard to read. Indent packages by two spaces?
  • after "will delete" and before "will mark" there are two empty lines, elsewhere just one

missing privilege escalation under Debian

I've installed pacdef on a fresh Ubuntu VM.
If I specify packages for [debian], I get the following:

zaubentrucker@pita-ubuntu:~$ pacdef package sync
WARNING: group file /home/zaubentrucker/.config/pacdef/groups/base is not a symlink
Would install the following packages:

[debian]
lolcat

[rust]
fd-find

Continue? [Y/n] 
E: Could not open lock file /var/lib/dpkg/lock-frontend - open (13: Permission denied)
E: Unable to acquire the dpkg frontend lock (/var/lib/dpkg/lock-frontend), are you root?
Error: running action

Caused by:
    0: installing packages
    1: command returned with exit code 100

This makes sense, since apt needs root rights for installing packages.
If I execute pacdef as root, it can't find my group files anymore and would probably fail trying to install packages through cargo as well.

Am I just not using the tool in the right way?
Or should pacdef try to acquire root rights if apt is called?

AUR install fails

Describe the bug
When I try to install pacdef via AUR with yay, it fails.
I installed it using pip install from cloned repo and it works great.

Affected version
Output of pacdef version: na

Output of python --version: Python 3.10.8

Operating System

Arch-Linux

To Reproduce
Steps to reproduce the behavior:

  1. yay -S pacdef

Expected behavior
pacdef installs

Logs and outputs

________________________________________ ERROR collecting tests/test_aur_helper.py _________________________________________
ImportError while importing test module '/home/user/.cache/yay/pacdef/src/pacdef-0.8.0/tests/test_aur_helper.py'.
Hint: make sure your test modules/packages have valid Python names.
Traceback:
/usr/lib/python3.10/importlib/__init__.py:126: in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
tests/test_aur_helper.py:10: in <module>
    from tests.constants import PACMAN, PACMAN_EXISTS, REASON_NOT_ARCH
E   ModuleNotFoundError: No module named 'tests.constants'
__________________________________________ ERROR collecting tests/test_pacdef.py ___________________________________________
ImportError while importing test module '/home/user/.cache/yay/pacdef/src/pacdef-0.8.0/tests/test_pacdef.py'.
Hint: make sure your test modules/packages have valid Python names.
Traceback:
/usr/lib/python3.10/importlib/__init__.py:126: in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
tests/test_pacdef.py:16: in <module>
    from test_aur_helper import TestAURHelper
tests/test_aur_helper.py:10: in <module>
    from tests.constants import PACMAN, PACMAN_EXISTS, REASON_NOT_ARCH
E   ModuleNotFoundError: No module named 'tests.constants'
================================================= short test summary info ==================================================
ERROR tests/test_aur_helper.py
ERROR tests/test_pacdef.py

build against rust-apt v0.7.0 broken

error[E0599]: no method named `name` found for opaque type `impl Iterator<Item = rust_apt::package::Package<'_>>` in the current scope
  --> crates/pacdef_core/src/backend/actual/debian.rs:38:45
   |
38 |             result.insert(Package::from(pkg.name().to_string()));
   |                                             ^^^^ method not found in `impl Iterator<Item = Package<'_>>`

error[E0599]: no method named `name` found for opaque type `impl Iterator<Item = rust_apt::package::Package<'_>>` in the current scope
  --> crates/pacdef_core/src/backend/actual/debian.rs:49:45
   |
49 |             result.insert(Package::from(pkg.name().to_string()));
   |                                             ^^^^ method not found in `impl Iterator<Item = Package<'_>>`

For more information about this error, try `rustc --explain E0599`.
error: could not compile `pacdef_core` (lib) due to 2 previous errors

properly handle imported group folders

Hi! Love the tool. I tried to create a pacdef folder in my personal vault (so my definitions get backed up properly) and then used pacdef group import.

~/.config/pacdef/groups now contains all my files as symlinks, which is perfect, however, because I use folders similar to the setup described in the readme, I now also get this error:

❯ pacdef group list
Error: loading groups under /home/btr/.config/pacdef/groups

Caused by:
    0: reading group file "/home/btr/.config/pacdef/groups/generic"
    1: reading file content
    2: Is a directory (os error 21)

I see three solutions for this:

  1. ignore folders when traversing down
  2. so you can have group files with the same name in different folders, make the group symlink a concatenated list of all folders down to the file. So the group file groups/generic/base would become a generic_base symlink.
  3. a combination of 1. and 2.: simply symlink one-to-one and ignore folder symlinks when traversing

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.