Giter VIP home page Giter VIP logo

tellery / tellery Goto Github PK

View Code? Open in Web Editor NEW
351.0 2.0 26.0 6.11 MB

Tellery lets you build metrics using SQL and bring them to your team. As easy as using a document. As powerful as a data modeling tool.

License: Apache License 2.0

Dockerfile 0.07% HTML 0.22% JavaScript 3.22% TypeScript 89.32% CSS 0.04% Shell 0.06% Kotlin 7.06%
notebook dashboard business-intelligence data-visualization data-science analytics data-analytics self-hosted data-modeling sql

tellery's Introduction

Tellery

Website | Demo | Docs | Changelog | Twitter

license

Tellery lets you build metrics using SQL and bring them to your team. Metrics are defined consistently and constantly updated, no longer scattered across tools, and recreated with no oversight.

Features

  • Let business users get answers in just a few clicks. No longer communicate in tables and columns.
  • Build beautiful documents & dashboards visually with drag-and-drop ease
  • An editor with rich text styling features, slash commands, and markdown support
  • A modern SQL editor with multi-tabs and auto-complete
  • Model your data with just SQL and reference like CTEs
  • Review work and collaborate in real-time with multiplayer
  • Import dbt models and sources and inspect their metadata while editing SQL

Supported databases

Recording

Tellery Product Usage Recording

Getting started

Try demo

Try this online demo where you can click around and see Tellery in action - no installation required!

Run the demo project with docker

Open your terminal, and run:

# Clone the Tellery repo
git clone https://github.com/tellery/tellery.git

# Change directories into the demo directory
cd tellery/deploy/compose

# View or edit config file (optional)
# vim .env

# Run docker compose
docker-compose up

You can now access it on http://localhost:8000.

The default account is [email protected] and password is tellery.

Production setup

Next step

Learn how to start analysis with Tellery:

Community support

  • Looking to get answers to questions? Join the chat on Discord
  • Want to report a bug or request a feature? Open an issue.
  • Read all the latest news on Twitter

Contributing

Contributions of any kind welcome! If you’re looking for ways to get started, here's a list of ways to help us improve Tellery:

tellery's People

Contributors

cosformula avatar dependabot[bot] avatar domechn avatar jhult avatar onesuper avatar raycursive avatar renzholy avatar talkwithkeyboard 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

tellery's Issues

Optimization: Executing multiple same SQL simultaneously

When multiple people execute the same SQL at the approach time, the backend should not send all of them to the connector. But only once then return the result to all requests.

Describe the solution you'd like

  • Calculate the Hash of SQL needs to be executed
  • Place Hash in a global storage ( pg or redis )
  • Before performing a SQL, first check the store to confirm if the SQL is currently being executed.
    • If the SQL is not being executed, submit it to the Connector and store it
    • If the SQL is being executed, waiting until the previous SQL is completed and return the result

Additional context

We need to take into account the expansion of Backend. Thus we need to save the results of SQL to global storage. Let the waiting request can get this result.

Maybe we can set an Index for each Pending SQL. When there is a executing sql request, make the Pending SQL's index plus 1. When the Pending request gets SQL Result, make the Pending SQL's index sub 1.

If the Index is 0, delete the Pending SQL Record.

RIP

RIP Tellery

Any way to run just the editor?

Really like the amazing editor you built (Notion-like editor). Wondering if there's a way to run just the editor alone? For example, as an npm package that has the self contained editor.

Create a query from the left sidebar

Creating query from the left sidebar will not create a associated visualization block in the current story

  • Create new query
  • Import from other story
  • Import a CSV file

All the queries listed in the left sidebar can be deleted/duplicated by the users who has write access to the story.

It is a good time to refactor connector

Is your feature request related to a problem? Please describe.
We base on some principles to refactor connector server:

  1. Profile system is base on the file system, it is unsuitable to be handle in multiply pods.
  2. In the foreseeable future, some modules will provide two implements for on-prem and SaaS, the current code architecture can't handle the feature very well.
  3. It's hard for community users to contribute code about integration or create a new integration.

Describe the solution you'd like

  1. We provide a common interface and two implements:
  • file system implement just for the on-prem users.
  • database implement for cluster users.
  1. Import an injection framework to solve the problem, Koin may be the most succinct choice, and then update some managers and services to fit the injection framework.
  2. Refactor integration module, decoupling it with profile module.

UnauthorizedError: not exist - After deploying through docker

Describe the bug
After following the steps mentioned in GitHub to deploy Tellery locally, I am getting UnauthorizedError: not exist error every time even after clean installtion.

tellery-server_1 | <-- GET /
tellery-server_1 | xxx GET / 401 33ms -
tellery-server_1 | UnauthorizedError: not exist
tellery-server_1 | at Function.notExist (/tellery/dist/src/error/error.js:46:16)
tellery-server_1 | at UserService.verifyToken (/tellery/dist/src/services/user.js:154:45)
tellery-server_1 | at processTicksAndRejections (node:internal/process/task_queues:96:5)
tellery-server_1 | at async user (/tellery/dist/src/middlewares/user.js:23:23)
tellery-server_1 | at async logger (/tellery/node_modules/koa-logger/index.js:67:7)
tellery-server_1 | at async error (/tellery/dist/src/middlewares/error.js:5:9) {
tellery-server_1 | status: 401
tellery-server_1 | }
tellery-server_1 | <-- GET /favicon.ico
tellery-server_1 | xxx GET /favicon.ico 401 6ms -
tellery-server_1 | UnauthorizedError: not exist
tellery-server_1 | at Function.notExist (/tellery/dist/src/error/error.js:46:16)
tellery-server_1 | at UserService.verifyToken (/tellery/dist/src/services/user.js:154:45)
tellery-server_1 | at processTicksAndRejections (node:internal/process/task_queues:96:5)
tellery-server_1 | at async user (/tellery/dist/src/middlewares/user.js:23:23)
tellery-server_1 | at async logger (/tellery/node_modules/koa-logger/index.js:67:7)
tellery-server_1 | at async error (/tellery/dist/src/middlewares/error.js:5:9) {
tellery-server_1 | status: 401

And if I go to http://localhost:8000/ I get {"errMsg":"not exist"}

To Reproduce
Steps to reproduce the behavior:

  1. Go to installation directory and docker-compose up.
  2. See error

Expected behavior
Expect to run on local server smoothly

Screenshots
image

Desktop (please complete the following information):

  • OS: MacOS 11.5.2 (Intel i7)
  • Browser: Chrome
  • Version: 92

Pull Request Preview Environments for increasing maintainer productivity

I would like to make life easier for Tellery maintainers by implementing Uffizzi preview environments.
Disclaimer: I work on Uffizzi.

Uffizzi is a Open Source full stack previews engine and our platform is available completely free for Tellery (and all open source projects). This will provide maintainers with preview environments of their PRs in the cloud, allowing them iterate faster and reduce time to merge.

Uffizzi is purpose-built for the task of previewing PRs and it integrates with your workflow to deploy preview environments in the background without any manual steps for maintainers or contributors.

TODO:

  • Intial PoC

BEI: Support custom blocks in the Backend

Is your feature request related to a problem? Please describe.

We should allow developers to add a custom Block in Tellery by writing certain functions.

Describe the solution you'd like

This feature can be implemented by defining an Interface which call BlockExtensionInterface(BEI).

What is the BEI like

BlockExtensionInterface interface {
  
}

Additional context

Now there is a little doubt that whether the ext blocks can be loaded dynamically. If we need to achieve this future, there are two ways.

  1. Start a process for the BEI plugin, communicate by RPC or other means
  2. Start a VM in Nodejs to dynamically execute the BEI code

If the first method is used, the management difficulty of service will rise. If you use the second method, this means that all backend services must share a store to ensure that the same BEI code is obtained.

TODO List

  • Define BEI
  • Decoupled the relationship betwen QuestionBlocks and SQL Execution

Metric exploration query builder

Drag-and-drop a data asset from the left sidebar to story:

  • A query will be generated to explore the configured metrics of the data asset
  • An exeuction will be trigger against the query to fetch results
  • A visualization block will be created and connected to that query

node-cache-manager is not used correctly

Describe the bug

When using pg, the cache cannot be shared when there are multiple backend instances.

As a result, online users cannot be aggregated and counted in socket services.

Additional context

The reason for this problem is that no external cache is used when using node-cache-manager.

} else {
externalCache = memoryCache.get()
}

ps: there is currently no implementation of the node-cache-manager with postgresql.

Optimization: Better profile storage

Is your feature request related to a problem? Please describe.
Storing profile as a json file is a fault of early design since in the very beginning we didn't consider modifying profiles from web UI. Currently, we met the following issues:

Issue 1: mount profile by configMap in k8s => not be able to update the profile from web UI, since the file is read-only.

Issue 2: It's hard to handle the case of multiple instances writing into a single file.

Describe the solution you'd like
The connector should connect to a Postgres to store profile, and a redis as an event bus in HA usage (this could opt-out)

For simple deployment (i.e., without HA), the Postgres can be replaced by a sqlite maybe?

Create metrics against columns of a data asset

A metric must be associated with a column of the data asset.

A metric contains two parts:

  • An aggregation function used to calculate the metric, like sum,avg
  • A name for description purpose

Decouple the isAnonymous function from the logout interface

In normal mode, the cookie in the browser is cleared when the user logs out.
In anonymous mode, users cannot actively log out.

The current approach is to call the isAnonymous function directly in router.ts to determine whether it is in anonymous mode.

But in fact, we have implemented AnonymousUserService, and we can implement the logic of logout in UserService and AnonymousUserService.

You can implement the logout method in UserService and return a boolean to determine whether the cookie is clear or not

async function logout(ctx: Context) {
// for anonymous user service, logout does not clean cookies / header
if (!isAnonymous()) {
setToken(ctx, null)
}
ctx.body = { success: true }
}

Deleted block appears in the first story of local deployment

Describe the bug
After deploying the service locally and logged in, the first block of the first story shows "deleted block"

To Reproduce
Steps to reproduce the behavior:

  1. deploy the server by docker-compose
  2. log in
  3. go to the first story

Expected behavior
Appears the visualization of Iris data set

What editor used under the hood?

Hi, I was curious what editor was used for text editing (like DraftJS, CKEditor, or Prosemirror etc.) but couldn't find anything that would give me the clue. Was the Tellery editor write from scratch?

Is it possible to connect Clickhouse database?

Is your feature request related to a problem? Please describe.
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]

Describe the solution you'd like
A clear and concise description of what you want to happen.

Describe alternatives you've considered
A clear and concise description of any alternative solutions or features you've considered.

Additional context
Add any other context or screenshots about the feature request here.

Quick Setup 获取镜像失败

Describe the bug
获取镜像失败

To Reproduce
Steps to reproduce the behavior:
1、使用 docker 安装案例,进行到docker-compose up时无法拉取镜像
`% docker-compose up

WARNING: The EMIAL_PORT variable is not set. Defaulting to a blank string.
WARNING: The EMIAL_HOST variable is not set. Defaulting to a blank string.
WARNING: The EMIAL_FROM variable is not set. Defaulting to a blank string.
Pulling redis (redis:6.2.4)...
ERROR: Head https://registry-1.docker.io/v2/library/redis/manifests/6.2.4: Get https://auth.docker.io/token?scope=repository%3Alibrary%2Fredis%3Apull&service=registry.docker.io: EOF`

Expected behavior

Screenshots
image
Desktop (please complete the following information):

  • OS: [e.g. MacOS ]

Additional context
Add any other context about the problem here.

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.