|
1 |
| -# Infactory - Development |
| 1 | +# Infactory SDK |
2 | 2 |
|
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. |
4 | 4 |
|
5 |
| - |
6 |
| - |
7 |
| - |
8 |
| -[](/#) |
| 5 | +## Installation |
9 | 6 |
|
10 |
| -## Running Locally |
| 7 | +```bash |
| 8 | +pip install infactory |
| 9 | +``` |
11 | 10 |
|
12 |
| -### Using Docker |
| 11 | +## Getting Started |
13 | 12 |
|
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: |
15 | 16 |
|
16 | 17 | ```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 |
20 | 20 |
|
21 |
| -# build it |
22 |
| -docker compose build --builder multiarch --push |
| 21 | +# Or use the CLI login command |
| 22 | +nf login |
23 | 23 | ```
|
24 | 24 |
|
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 |
26 | 30 |
|
27 | 31 | ```bash
|
28 |
| -docker compose up |
| 32 | +$ nf login |
| 33 | +Enter your API key: ******************** |
| 34 | +API key saved successfully! |
29 | 35 | ```
|
30 | 36 |
|
31 |
| -### Using Minikube (Kubernetes) |
| 37 | +### 2. Connect a Postgres datasource |
32 | 38 |
|
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 | +``` |
34 | 49 |
|
35 |
| -If you're on a Mac, you can install `kubectl` and `minikube` via Homebrew: |
| 50 | +### 3. Subscribe to jobs for the data source |
36 | 51 |
|
37 | 52 | ```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 |
40 | 60 | ```
|
41 | 61 |
|
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 |
45 | 63 |
|
46 | 64 | ```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 |
50 | 72 | ```
|
51 | 73 |
|
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 |
53 | 75 |
|
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 | +``` |
55 | 91 |
|
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 |
57 | 93 |
|
58 | 94 | ```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 |
68 | 99 | ```
|
69 | 100 |
|
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 | +``` |
71 | 113 |
|
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 |
73 | 115 |
|
74 | 116 | ```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" |
77 | 123 | ```
|
78 | 124 |
|
79 |
| -Note that while minikube is running, the Kubernetes `context` is set to Minikube. |
| 125 | +## Python SDK Examples |
80 | 126 |
|
81 |
| -## Contributing |
| 127 | +The Infactory Python SDK provides a simple interface to interact with the Infactory platform. |
82 | 128 |
|
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 |
84 | 130 |
|
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 |
86 | 133 |
|
87 |
| - |
| 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 | +``` |
88 | 138 |
|
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 |
90 | 140 |
|
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") |
92 | 144 |
|
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 | +) |
94 | 151 |
|
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 | +) |
96 | 157 |
|
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 | +``` |
98 | 160 |
|
99 |
| -### Environment Setup |
| 161 | +### 3. List datalines in the project |
100 | 162 |
|
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) |
108 | 166 |
|
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 | +``` |
115 | 170 |
|
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 | +``` |
117 | 195 |
|
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 |
121 | 197 |
|
122 |
| -### Tests |
| 198 | +```python |
| 199 | +# Evaluate the query program |
| 200 | +result = client.query_programs.evaluate(query_program.id) |
123 | 201 |
|
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 | +``` |
125 | 205 |
|
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}") |
129 | 243 | ```
|
130 | 244 |
|
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 |
132 | 246 |
|
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) |
136 | 257 | ```
|
137 | 258 |
|
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 |
139 | 260 |
|
140 |
| -### Versioning |
| 261 | +Check out our [documentation](https://docs.infactory.ai) for more information on advanced features such as: |
141 | 262 |
|
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 |
144 | 268 |
|
145 |
| -## Deploying |
| 269 | +## Support |
146 | 270 |
|
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