diff --git a/README.md b/README.md index ef46f3b..a710513 100644 --- a/README.md +++ b/README.md @@ -1,197 +1,113 @@ -

SocAIty SDK

- + SocAIty SDK. Any AI model. One call.

-

Build AI-powered applications with ease

+

+ PyPI version + Python versions + Docs +

-The SDK provides generative models and AI tools across all domains including text, audio, image and more. -Our APIs and SDK allows you to run models as simple python functions. No GPU or AI knowledge required. -Build your dream application by composing different models together. - -If you are a Software Engineer, Game Developer, Artist, Content Creator and you want to automate with AI this SDK is for you. - -For an overview of all models and to obtain an API key visit [socaity.ai](https://www.socaity.ai) - -Run models as if they were python functions nomatter where they are deployed: - -You can focus on your app, while we handle all the complicated stuff under the hood. - -
- -Quicklinks: -- [Quick Start](#quick-start) contains a simple example to get you started -- [Models Zoo](#model-zoo) an overview of all models. -- [Working locally or with other providers](#working-locally-or-with-other-providers) +

Any AI model. One call. Run AI on your terms.

-
+

+ 441 hosted models across image, audio, video and text, called like plain Python functions.
+ No GPU, no infrastructure, no AI background required. +

-# Getting started +## Install -## Installation -Install the package from PyPi ```bash pip install socaity ``` -### Installing Models -The SDK now supports selective installation of models to keep your environment clean. -By default, only official models are updated/installed. You can install additional models via CLI or Python. +Grab a key at [socaity.ai](https://www.socaity.ai) and set it once: -**CLI Usage:** ```bash -# Install a specific model -socaity -install model_name_or_id -# OR -socaity -i model_name_or_id +export SOCAITY_API_KEY="sk_..." +``` -# Install all available models -socaity -i all +## Quick start -# Install via python module -python -m socaity install model_name_or_id -``` +One call installs the model, runs it, and returns a typed result: -**Python Usage:** ```python import socaity -# Install a specific model -socaity.install("model_name_or_id") - -# Install all models -socaity.install("all") +img = socaity.run("black-forest-labs/flux-schnell", prompt="a neon fox") +img.save("fox.png") ``` -## Authentication - -For using socaity.ai services you need to set the environment variable `SOCAITY_API_KEY`. -You can obtain an API key from [socaity.ai](https://www.socaity.ai) after signing up. -Now you are ready to use the SDK. +That is the whole loop. `socaity.run` reads your key from `SOCAITY_API_KEY`, so there is nothing else to wire up. -**Alternatively** you can set the API key in your code when using the SDK. -We don't recommend this, as it a common mistake to push your code including your API key to a public repository. -```python -from socaity import face2face -f2f = face2face(api_key="sk..your_api_key") -``` -# Quick start - -Import a model from the model-zoo or just use the simple API (text2img, text2speech etc.) -```python -from socaity import speechcraft -audiogen = speechcraft(api_key=os.getenv("SOCAITY_API_KEY")) -``` -Then you can use it as a function -```python -audio_job = audiogen.text2voice(text="welcome to generative ai", voice="hermine") -audio_job.get_result().save("welcome.mp3") -``` +## Working with models directly -### Example 1: Combine llm, text2img and text2speech +`run` is the shortcut. When you want the typed client (autocomplete, named parameters, reuse), install the model once and import it: -We will use different models to showcase how to create for example a perfect combination for a blog. ```python import os -from socaity import speechcraft -from socaity.sdk.replicate.deepseek_ai import deepseek_v3 -from socaity.sdk.replicate.black_forest_labs import flux_schnell +import socaity -sk_api_key = os.getenv("SOCAITY_API_KEY") +socaity.install("deepseek-ai/deepseek-v3") # generates the typed client -deepseek = deepseek_v3(api_key=sk_api_key) -poem = deepseek(prompt="Write a poem with 3 sentences why a SDK is so much better than plain web requests.").get_result() -poem = "".join(poem) +from socaity.replicate.deepseek_ai import deepseek_v3 -audiogen = speechcraft(api_key=sk_api_key) -audio = audiogen.text2voice(text=poem, voice="hermine") +llm = deepseek_v3(api_key=os.getenv("SOCAITY_API_KEY")) +job = llm(prompt="write a haiku about cold starts") # returns a job, does not block +text = "".join(str(chunk) for chunk in job.get_result()) +``` -my_image_prompt = """ -A robot enjoying a stunning sunset in the alps. In the clouds is written in big letters "SOCAITY SDK". -The sky is lit with deep purple and lime colors. It is a wide-shot. -The artwork is striking and cinematic, showcasing a vibrant neon-green lime palette, rendered in an anime-style illustration with 4k detail. -Influenced by the artistic styles of Simon Kenny, Giorgetto Giugiaro, Brian Stelfreeze, and Laura Iverson. -""" +Every call returns a job immediately, so you can start several and collect them later. Hosted models live under `socaity.replicate.`, with names normalized to valid Python (for example `black-forest-labs` becomes `black_forest_labs`). -flux = flux_schnell(api_key=sk_api_key) -images = flux(prompt=my_image_prompt, num_outputs=1, seed=12).get_result() -for i, img in enumerate(images): - img.save(f"sdk_poem_{i}.png") +You can also install from the command line (run `socaity login` once first): -audio.get_result().save("sdk_poem.mp3") +```bash +socaity install black-forest-labs/flux-schnell ``` -This results in something like this: -https://github.com/user-attachments/assets/978ee377-3ceb-4a87-add5-daee15306231 +## Results and files -### Jobs vs. Results +A call with a single output returns one typed object. Ask for more and you get a list: -When you invoke an service, internally we use threading and asyncio to check the socaity endpoints for the result. -This makes it possible to run multiple services in parallel and is very efficient. ```python -# the base method always returns a job -d_job = deepseek_v3("what a time to be alive") -# in the meantime you can call other services or do what you want -... do other things here ... -# when you need the result you can call get_result() -poem = d_job.get_result() +imgs = socaity.run("black-forest-labs/flux-schnell", prompt="a neon fox", num_outputs=4) +for i, img in enumerate(imgs): + img.save(f"fox_{i}.png") ``` -# Model zoo - -A curated list of hosted models you always find on [socaity.ai](https://www.socaity.ai). - -To start here's a list of some of the models you can use with the SDK. -Just import them with ```from socaity import ...``` to use them. - -### Text domain -- DeepSeek models -- OpenAPI models -- LLama3 Family (8b, 13b, 70b models) +Inputs and outputs are typed media objects (`ImageFile`, `AudioFile`, `VideoFile`), importable straight from the package: -### Image domain -- FluxSchnell (Text2Image) -- SAM2 (Image and video segmentation) -- TencentArc Photomaker - -### Audio domain -- [SpeechCraft](https://github.com/SocAIty/SpeechCraft) (Text2Voice, VoiceCloning) - - -Note that we have just launched the startup. Expect new models coming highly frequently. - - -# Working locally or with other providers - -Any service that is [fastSDK](https://github.com/SocAIty/fastsdk) compatible (openAPI / [APIPOD](https://github.com/SocAIty/APIPod), replicate and [runpod](https://www.runpod.io/)) -can be used with this package. - -Model deployment type | Description | Pros | Cons -------------- |----------------------------------------------------------------|------------------------------------------------| ------------ -Locally | Install genAI packages on your machine and use it with socaity | Free, Open-Source | GPU needed, more effort -Hosted | Use the AIs hosted on socaity servers or of another provider. | Runs everywhere, Ultra-easy, always up to date | Slightly higher cost -Hybrid | Deploy on runpod, locally and use socaity services. | Full flexibility | Effort +```python +from socaity import ImageFile +portrait = ImageFile().from_file("portrait.jpg") +``` +## Models +441 hosted models, Replicate backed, across every domain: -### Hosting a service on Socaity.ai +| Domain | Examples | +|--------|----------| +| Image | `black-forest-labs/flux-schnell`, `tencentarc/gfpgan` | +| Text | `deepseek-ai/deepseek-v3`, `meta/meta-llama-3-70b` | +| Audio | `jaaari/kokoro-82m`, `vaibhavs10/incredibly-fast-whisper` | +| Video | `tencent/hunyuan-video` | -Any service created with [apipod]() can be hosted on socaity.ai for free if made public. You can even earn some credits. -The service will then be added to the socaity SDK. -Checkout [https://www.socaity.ai] for more information. +The full, always current list lives at [socaity.ai](https://www.socaity.ai). -Furthermore: any service that is created with [APIPod](https://github.com/SocAIty/APIPod) can be easily used in combination with [FastSDK](https://github.com/SocaIty/fastsdk). -Checkout the [FastSDK](https://github.com/SocaIty/fastsdk) documentation for more information. +## Local and self hosted +Open source services like [face2face](https://github.com/SocAIty/face2face) and [SpeechCraft](https://github.com/SocAIty/SpeechCraft) are not in the hosted catalog. Run them yourself with [APIPod](https://github.com/SocAIty/APIPod) and drive them through the same SDK. Anything [fastSDK](https://github.com/SocAIty/fastSDK) compatible (OpenAPI, APIPod, Replicate, RunPod) plugs in. -# Important Note -PACKAGE IS IN ALPHA RELEASE. -EXPECT RAPID CHANGES TO SYNTAX AND FUNCTIONALITY. +| Where it runs | Trade off | +|---------------|-----------| +| Hosted on socaity.ai | zero setup, always current, slight cost | +| Local on your machine | free and open source, needs a GPU | +| Hybrid, RunPod or local plus socaity | full control, more effort | -# Contribute +We handle the DevOps. You ship the app. -Any help with maintaining and extending the package is welcome. -Feel free to open an issue or a pull request. +## Status -## PLEASE LEAVE A :star: TO SUPPORT THIS WORK +Alpha. Expect rapid changes to syntax and surface. Issues and pull requests are welcome. diff --git a/docs/UseCases.md b/docs/UseCases.md index 93c0ffe..8e24dfe 100644 --- a/docs/UseCases.md +++ b/docs/UseCases.md @@ -1,17 +1,26 @@ -# Examples and Use-Cases +# Examples and use cases -The future of the Internet and the economy is generative. However, there's not one model that fits all. -For real world applications, you need to chain different models together combine them with other services. +Most real applications chain a few models together. With `socaity.run` each step is a single call, so a whole pipeline stays readable. -AI NPC Agents - How to: -Here's a common example of a game developer who wants to have AI NPC agents in his game. His workflow: -1. Generate the text the NPC should say. -2. use a `text2speech` model to synthesize speech for the NPC. -3. uses the `voice2voice` model to change the voice of the NPC to one of his artists. -4. uses `audio2face` model to generate facial animations for the NPC. +## Narrated explainer -Automated video content - How to: -1. Create a thumbnail for a video with `text2image` -2. Swap the faces in the video with `face2face` -3. Generate a voice-over for the video with `text2voice` +Write the script with an LLM, generate a cover image, and synthesize a voiceover. Three calls, three models: +```python +import socaity + +script = "".join(str(chunk) for chunk in socaity.run( + "deepseek-ai/deepseek-v3", + prompt="Write two sentences explaining serverless GPU hosting.", +)) + +cover = socaity.run("black-forest-labs/flux-schnell", prompt="abstract lime on black, minimal") +voice = socaity.run("jaaari/kokoro-82m", text=script, voice="af_bella") + +cover.save("cover.png") +voice.save("voiceover.wav") +``` + +`socaity.run` reads your `SOCAITY_API_KEY` from the environment and returns a typed result per model: text chunks from the LLM, an `ImageFile` from flux, an `AudioFile` from kokoro. + +Pick any of the 441 models at [socaity.ai](https://www.socaity.ai) and pass its inputs the same way. diff --git a/docs/assets/banner.html b/docs/assets/banner.html new file mode 100644 index 0000000..76653ca --- /dev/null +++ b/docs/assets/banner.html @@ -0,0 +1,117 @@ + + + + + + + + + + + + + + diff --git a/docs/assets/banner.png b/docs/assets/banner.png new file mode 100644 index 0000000..6d4891d Binary files /dev/null and b/docs/assets/banner.png differ diff --git a/docs/assets/socaity_logo.png b/docs/assets/socaity_logo.png new file mode 100755 index 0000000..c5b9900 Binary files /dev/null and b/docs/assets/socaity_logo.png differ diff --git a/socaity/__init__.py b/socaity/__init__.py index 30999bd..5e778dd 100644 --- a/socaity/__init__.py +++ b/socaity/__init__.py @@ -1,7 +1,10 @@ +import os +import importlib from pathlib import Path from media_toolkit import MediaFile, ImageFile, VideoFile, AudioFile -from fastsdk import FastSDK +from fastsdk import FastSDK, FastClient +from apipod_registry.utils.normalization import normalize_name_for_py from socaity.core.socaity_service_registry import SocaityServiceRegistry service_registry = FastSDK().service_registry = SocaityServiceRegistry() @@ -26,10 +29,54 @@ def install(service_name_or_id: str) -> None: service_registry.install_service(service_name_or_id) +def run(service_name_or_id: str, *, api_key: str = None, **inputs): + """Install if needed, run a model, and return its result in one call. + + A shortcut over the install, import and call steps: + + img = socaity.run("black-forest-labs/flux-schnell", prompt="a neon fox") + img.save("fox.png") + + api_key defaults to the SOCAITY_API_KEY environment variable. + """ + model_cls = _resolve_model_class(service_name_or_id) + if model_cls is None: + install(service_name_or_id) + model_cls = _resolve_model_class(service_name_or_id) + if model_cls is None: + raise ValueError(f"Could not resolve or install service '{service_name_or_id}'.") + model = model_cls(api_key=api_key or os.getenv("SOCAITY_API_KEY")) + return model(**inputs).get_result() + + +def _resolve_model_class(service_name_or_id: str): + """Return the generated FastClient subclass for a service, or None if not installed yet.""" + service_def = service_registry.get_service(service_name_or_id) + if service_def is not None: + try: + module = importlib.import_module( + f"socaity.sdk.services.{normalize_name_for_py(service_def.id)}" + ) + for value in vars(module).values(): + if isinstance(value, type) and issubclass(value, FastClient) and value is not FastClient: + return value + except ModuleNotFoundError: + pass + # Fallback: resolve via the public replicate namespace (vendor/model) + if "/" in service_name_or_id: + vendor, model = service_name_or_id.split("/", 1) + try: + namespace = importlib.import_module(f"socaity.replicate.{normalize_name_for_py(vendor)}") + return getattr(namespace, normalize_name_for_py(model), None) + except ModuleNotFoundError: + pass + return None + + # Re-export official services at top level: from socaity import face2face try: from socaity.sdk.official import * # noqa: F401,F403 except ImportError: pass -__all__ = ["install", "service_registry", "MediaFile", "ImageFile", "VideoFile", "AudioFile"] +__all__ = ["install", "run", "service_registry", "MediaFile", "ImageFile", "VideoFile", "AudioFile"]