Skip to content

Commit 4d88454

Browse files
committed
WIP: cli
1 parent 8a772ff commit 4d88454

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

58 files changed

+236
-10087
lines changed

.env

Lines changed: 0 additions & 3 deletions
This file was deleted.

.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,3 +64,7 @@ target/
6464

6565
#Ipython Notebook
6666
.ipynb_checkpoints
67+
.env
68+
69+
repomix-output.txt
70+
openapi.json

README.md

Lines changed: 210 additions & 86 deletions
Original file line numberDiff line numberDiff line change
@@ -1,147 +1,271 @@
1-
# Infactory - Development
1+
# Infactory SDK
22

3-
This repository contains the back-end execution and query environment for the Infactory platform.
3+
The Infactory SDK provides simple and powerful interfaces to work with your data and AI services. It allows you to connect your data sources, create query programs, and publish them as APIs, all from your terminal or Python code.
44

5-
![Latest_Release](https://img.shields.io/github/v/release/infactory-io/dev)
6-
![Tests](https://github.com/infactory-io/dev/actions/workflows/tests.yml/badge.svg)
7-
![Coverage](./docs/images/coverage.svg)
8-
[![Language](https://img.shields.io/badge/python-3.11%20%7C%203.12-blue)](/#)
5+
## Installation
96

10-
## Running Locally
7+
```bash
8+
pip install infactory
9+
```
1110

12-
### Using Docker
11+
## Getting Started
1312

14-
First, ensure your environment is setup (take a look at the `Contributing: Environment Setup` below):
13+
### Setting your API Key
14+
15+
Before using the SDK, you need to set your API key. You can either set it as an environment variable or use the CLI login command:
1516

1617
```bash
17-
# create the multi-platform build environment / driver
18-
docker buildx create --name multiarch --use
19-
docker buildx inspect --bootstrap
18+
# Set the API key as an environment variable
19+
export NF_API_KEY=your_api_key_here
2020

21-
# build it
22-
docker compose build --builder multiarch --push
21+
# Or use the CLI login command
22+
nf login
2323
```
2424

25-
Then:
25+
## CLI Examples
26+
27+
The Infactory CLI (`nf`) provides a set of commands to interact with the Infactory platform.
28+
29+
### 1. Login to Infactory
2630

2731
```bash
28-
docker compose up
32+
$ nf login
33+
Enter your API key: ********************
34+
API key saved successfully!
2935
```
3036

31-
### Using Minikube (Kubernetes)
37+
### 2. Connect a Postgres datasource
3238

33-
The Infactory framework leverages [Kubernetes](https://kubernetes.io) to deploy, scale and manage micro services, databases and other containerized applications within the framework. To leverage Kubernetes and run the framework locally, please install both [kubectl](https://kubernetes.io/docs/reference/kubectl/) and [minikube](https://minikube.sigs.k8s.io/docs/start/?arch=%2Fmacos%2Farm64%2Fstable%2Fbinary+download) (which runs in Docker).
39+
```bash
40+
$ nf datasource create --name "Product Database" --type postgres --project-id my-project-id
41+
Datasource created successfully!
42+
ID: ds-abc123
43+
Name: Product Database
44+
Type: postgres
45+
46+
$ nf datasource configure ds-abc123 --uri "postgresql://username:password@host:port/database"
47+
Datasource configured successfully!
48+
```
3449

35-
If you're on a Mac, you can install `kubectl` and `minikube` via Homebrew:
50+
### 3. Subscribe to jobs for the data source
3651

3752
```bash
38-
brew install kubectl
39-
brew install minikube
53+
$ nf jobs subscribe --datasource-id ds-abc123
54+
Subscribing to jobs for datasource ds-abc123...
55+
[2025-03-25 14:30:21] Job j-123456 started: Connecting to PostgreSQL database
56+
[2025-03-25 14:30:22] Job j-123456 progress: Successfully connected to database
57+
[2025-03-25 14:30:25] Job j-123456 progress: Analyzing table structure
58+
[2025-03-25 14:30:30] Job j-123456 progress: Found 12 tables with 450,000 rows total
59+
[2025-03-25 14:30:45] Job j-123456 completed: Database connection established and schema analyzed
4060
```
4161

42-
Some folks on Macs report having issues installing the ARM tailored versions using `homebrew`. If that's what you run into, check out [these instructions](https://kubernetes.io/docs/tasks/tools/install-kubectl-macos/).
43-
44-
Now, do this:
62+
### 4. Generate a query program
4563

4664
```bash
47-
cd deploy
48-
chmod u+x ship_it.sh
49-
sh ship_it.sh
65+
$ nf query generate --dataline-id dl-456def --name "Monthly Sales by Region"
66+
Query program generation started...
67+
Analyzing data structure...
68+
Generating query program...
69+
Query program created successfully!
70+
ID: qp-789ghi
71+
Name: Monthly Sales by Region
5072
```
5173

52-
If you're on the `dev` branch or another branch, this script will deploy the Infactory framework to your local Minikube Kubernetes cluster. If on `staging` or `main`, the deployments will be pushed to the AWS Kubernetes cluster running in EKS, either on the `staging` or `prod` namespaces (respectively).
74+
### 5. Run the new code
5375

54-
#### More Info
76+
```bash
77+
$ nf query run qp-789ghi
78+
Running query program qp-789ghi...
79+
Results:
80+
+----------+--------+-------------+
81+
| Month | Region | Total Sales |
82+
+----------+--------+-------------+
83+
| Jan 2025 | North | $245,678.90 |
84+
| Jan 2025 | South | $198,432.45 |
85+
| Jan 2025 | East | $312,567.80 |
86+
| Jan 2025 | West | $276,543.21 |
87+
| Feb 2025 | North | $267,890.12 |
88+
| Feb 2025 | South | $210,987.65 |
89+
...
90+
```
5591

56-
Minikube will start a local Kubernetes server to deploy the Infactory framework and is essentially a mini Kubernetes cluster running on your local environment - very useful. To get going:
92+
### 6. Publish the query program
5793

5894
```bash
59-
minikube config set driver docker # first time only, make sure you have Docker installed. You can confirm using `minikube config view`
60-
minikube start
61-
minikube addons enable ingress
62-
kubectl config use-context minikube
63-
kubectl config set-context --current --namespace=dev
64-
kubectl cluster-info
65-
>>>
66-
Kubernetes control plane is running at https://127.0.0.1:57094
67-
CoreDNS is running at https://127.0.0.1:57094/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy
95+
$ nf query publish qp-789ghi
96+
Publishing query program qp-789ghi...
97+
Query program published successfully!
98+
Endpoint URL: https://i7y.dev/v1/live/monthly-sales/v1/data
6899
```
69100

70-
To stop the Minikube and any containers within the Minikube Kubernetes environment, simply `minikube stop`. You can then delete all Kubernetes clusters in Minikube by executing `minikube delete --all`.
101+
### 7. Display the available endpoints
102+
103+
```bash
104+
$ nf endpoints list --project-id my-project-id
105+
+-------------+-----------------+----------------------------------+--------+
106+
| Endpoint ID | Name | URL | Method |
107+
+-------------+-----------------+----------------------------------+--------+
108+
| ep-123abc | Monthly Sales | /v1/live/monthly-sales/v1/data | GET |
109+
| ep-456def | Product Details | /v1/live/product-details/v1/data | GET |
110+
| ep-789ghi | Customer Stats | /v1/live/customer-stats/v1/data | GET |
111+
+-------------+-----------------+----------------------------------+--------+
112+
```
71113

72-
The Minikube and Infactory Kubernetes environments are managed using [namespaces](https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/), which we use the same naming scheme and deployment structure as the cloud environments managed by Terraform: `dev`, `staging` and `prod`. To set and see the existing workspace set:
114+
### 8. Generate a CURL request for an endpoint
73115

74116
```bash
75-
kubectl config set-context --current --namespace=<insert-namespace-name-here> # set the new namespace, e.g. dev, staging or prod
76-
kubectl config view --minify | grep namespace: # validate new workspace
117+
$ nf endpoints curl-example ep-123abc
118+
CURL example for endpoint ep-123abc:
119+
120+
curl -X GET "https://i7y.dev/v1/live/monthly-sales/v1/data" \
121+
-H "Authorization: Bearer YOUR_API_KEY" \
122+
-H "Content-Type: application/json"
77123
```
78124

79-
Note that while minikube is running, the Kubernetes `context` is set to Minikube.
125+
## Python SDK Examples
80126

81-
## Contributing
127+
The Infactory Python SDK provides a simple interface to interact with the Infactory platform.
82128

83-
Please use the Linear issue tracker to report any erroneous behavior in need of fixes or desired feature requests.
129+
### 1. Import and setup
84130

85-
If you would like to contribute to development, branch off of `dev` and make contributions to a branch which corresponds to an open issue in [Linear](https://linear.app/infactoryio/team/TECH/all). In the Linear user interface, copy the git branch name, e.g. `tech-103-create-readme`:
131+
```python
132+
import infactory as nf
86133

87-
![linear_copy_git_branch_name](/docs/images/linear_copy_git_branch_name.png)
134+
# Initialize the client with your API key (or it will use NF_API_KEY environment variable)
135+
client = nf.Client(api_key="your_api_key_here")
136+
client.connect()
137+
```
88138

89-
When integrating fixes and features, open a pull request so that code contributions can be reviewed, tested, and documented using both human reviewers (developers and engineers) and automated checks (continuous integration).
139+
### 2. Create and configure a datasource
90140

91-
### Commit Messages and Releases
141+
```python
142+
# Get the current project or set a specific one
143+
project = client.projects.get("my-project-id")
92144

93-
Your commit messages are important - here's why.
145+
# Create a new datasource
146+
datasource = client.datasources.create(
147+
name="Product Database",
148+
project_id=project.id,
149+
type="postgres"
150+
)
94151

95-
Infactory leverages [release-please](https://github.com/googleapis/release-please-action) to help automate the release process using the [Conventional Commits](https://www.conventionalcommits.org/) specification. When pull requests are opened to the `main` branch, release-please will collate the git commit messages and prepare an organized changelog and release notes. This process can be completed because of the Conventional Commits specification.
152+
# Configure the datasource connection
153+
datasource = client.datasources.update(
154+
datasource.id,
155+
uri="postgresql://username:password@host:port/database"
156+
)
96157

97-
Conventional Commits provides an easy set of rules for creating an explicit commit history; which makes it easier to write automated tools on top of. This convention dovetails with SemVer, by describing the features, fixes, and breaking changes made in commit messages. You can check out examples [here](https://www.conventionalcommits.org/en/v1.0.0/#examples). Make a best effort to use the specification when contributing to Infactory code as it dramatically eases the documentation around releases and their features, breaking changes, bug fixes and documentation updates.
158+
print(f"Datasource created: {datasource.name} (ID: {datasource.id})")
159+
```
98160

99-
### Environment Setup
161+
### 3. List datalines in the project
100162

101-
1. First, install, setup and ensure the [Docker](https://www.docker.com/) engine is running on your local machine.
102-
The Infactory platform runs as a containerized unit.
103-
2. Python is used as part of the build process for the Docker container(s), so ensure Python is installed on your machine (versions 3.8 - 3.12).
104-
3. Create an ssh key to use for pulling Infactory code: `ssh-keygen -t rsa -b 4096 -f ~/.ssh/infactory-A`. Then `cd ~/.ssh`.
105-
4. `chmod 600 infactory-A`
106-
5. `chmod 644 infactory-A.pub`
107-
6. Create the config file `vim config`:
163+
```python
164+
# Get all datalines for the project
165+
datalines = client.datalines.list(project_id=project.id)
108166

109-
```bash
110-
Host *
111-
AddKeysToAgent yes
112-
UseKeychain yes # remove this line if on Linux and not on MacOS
113-
IdentityFile ~/.ssh/infactory-A
114-
```
167+
for dl in datalines:
168+
print(f"Dataline: {dl.name} (ID: {dl.id})")
169+
```
115170

116-
7. Copy the contents of `cat infactory-A.pub` into Github under >> `Settings` >> `SSH and GPG keys` >> `New SSH key`.
171+
### 4. Create a query program
172+
173+
```python
174+
# Choose a dataline from the list
175+
dataline = datalines[0]
176+
177+
# Create a new query program
178+
query_program = client.query_programs.create(
179+
name="Monthly Sales by Region",
180+
question="What are the monthly sales by region?",
181+
code="""
182+
import pandas as pd
183+
184+
def execute(df):
185+
# Group by month and region, sum sales
186+
result = df.groupby(['month', 'region'])['sales'].sum().reset_index()
187+
return result
188+
""",
189+
dataline_id=dataline.id,
190+
project_id=project.id
191+
)
192+
193+
print(f"Query program created: {query_program.name} (ID: {query_program.id})")
194+
```
117195

118-
8. Setup and activate the Python virtual environment: `python3 -m venv venv` and `source venv/bin/activate`
119-
9. Install the project requirements by navigating to `py/infactory` and running `pip install .`.
120-
10. Git LFS should be installed per the instructions [here](https://git-lfs.com/).
196+
### 5. Run the query program
121197

122-
### Tests
198+
```python
199+
# Evaluate the query program
200+
result = client.query_programs.evaluate(query_program.id)
123201

124-
When contributing, please ensure to run unit tests and add additional tests as necessary if adding new functionality. To run the tests and obtain test code coverage statistics, run the following from the root directory:
202+
print("Query results:")
203+
print(result)
204+
```
125205

126-
```bash
127-
pytest --cov=infactory --cov=infactory_api -s -v
128-
coveralls # to submit the report to https://coveralls.io/github/infactory-io/dev
206+
### 6. Publish the query program
207+
208+
```python
209+
# Publish the query program to make it available as an API
210+
published_program = client.query_programs.publish(query_program.id)
211+
212+
print(f"Query program published: {published_program.id}")
213+
```
214+
215+
### 7. Create an API endpoint
216+
217+
```python
218+
# Get API endpoints from the project
219+
apis = client.projects.get_apis(project.id)
220+
221+
if apis:
222+
api = apis[0]
223+
print(f"Using existing API: {api.name}")
224+
else:
225+
# Create a new API
226+
api = client.apis.create(
227+
name="Sales Analytics API",
228+
description="API for sales data analytics",
229+
project_id=project.id
230+
)
231+
print(f"Created new API: {api.name}")
232+
233+
# Create an endpoint for the query program
234+
endpoint = client.apis.create_endpoint(
235+
api_id=api.id,
236+
name="Monthly Sales",
237+
http_method="GET",
238+
description="Get monthly sales data by region",
239+
queryprogram_id=query_program.id
240+
)
241+
242+
print(f"Endpoint created: {endpoint.path}")
129243
```
130244

131-
You may need to install the Infactory framework in your virtual environment before running the tests along with Poetry:
245+
### 8. Get endpoint URL and details
132246

133-
```bash
134-
poetry install
135-
poetry run pytest --cov=infactory --cov=infactory_api -s -v
247+
```python
248+
# Get details for all endpoints in the API
249+
endpoints = client.apis.get_endpoints(api.id)
250+
251+
for ep in endpoints:
252+
print(f"Endpoint: {ep.name}")
253+
print(f"URL: https://i7y.dev/v1/live/{api.slug}/{api.version}/{ep.path}")
254+
print(f"Method: {ep.http_method}")
255+
print(f"Description: {ep.description}")
256+
print("-" * 50)
136257
```
137258

138-
In addition to being able to execute the tests locally using the above command, Github workflows are executed on the `main` and `dev` branches to ensure that the unit tests pass successfully. See the [coveralls.io](https://coveralls.io/github/infactory-io/dev?branch=main) report to see an interactive unit test code coverage report.
259+
## Advanced Features
139260

140-
### Versioning
261+
Check out our [documentation](https://docs.infactory.ai) for more information on advanced features such as:
141262

142-
[Semantic versioning](http://semver.org/) is used for this project. If contributing, please conform to semantic
143-
versioning guidelines. Future versioning may be handled by tools such as [release-please](https://github.com/googleapis/release-please-action).
263+
- Custom transformations and data processing
264+
- Automated data quality checks
265+
- Integration with ML models
266+
- Real-time data streaming
267+
- Team collaboration features
144268

145-
## Deploying
269+
## Support
146270

147-
See `deploy/readme.md`.
271+
If you need help or have any questions, please contact us at [email protected] or visit our [support portal](https://support.infactory.ai).

0 commit comments

Comments
 (0)