# OASist Client Generator
Generate type-safe Python clients from OpenAPI schemas with a beautiful CLI interface. Supports both JSON and YAML schemas with Orval-inspired configuration.
## Features
- 🚀 Single-file implementation with rich CLI interface
- 📦 Generate type-safe Python clients from OpenAPI specs (JSON/YAML)
- 🔄 Schema sanitization and validation
- 🎯 Orval-inspired configuration format
- 🏗️ Built with design patterns (Factory, Command, Dataclass)
- ⚡ Automatic base URL injection and post-hook management
- 🎨 Beautiful terminal UI with progress indicators
## Installation
```bash
# Install from PyPI
pip install oasist
```
## Quick Start
```bash
# List all configured services
oasist list
# Generate a specific client
oasist generate user
# Generate all clients
oasist generate-all
# Show service details
oasist info user
# Force regenerate existing client
oasist generate user --force
```
## Configuration
### Configuration
The generator supports both JSON and YAML OpenAPI documents. It pre-fetches the schema with optional headers/params, then generates via a local temp file to ensure consistent handling of JSON and YAML. Configuration is provided via a single JSON file using an Orval-inspired "projects" structure.
Create `oasist_config.json` in your project root:
```json
{
"output_dir": "./test",
"projects": {
"user_service": {
"input": {
"target": "http://localhost:8001/openapi.json",
"prefer_json": true
},
"output": {
"dir": "user_service",
"name": "User Service",
"base_url": "http://localhost:8001",
"package_name": "user_service",
"disable_post_hooks": true
}
},
"communication_service": {
"input": {
"target": "http://localhost:8002/openapi.json"
},
"output": {
"dir": "communication_service",
"name": "Communication Service",
"base_url": "http://localhost:8002",
"package_name": "communication_service",
"disable_post_hooks": true
}
},
"local_yaml": {
"input": {
"target": "http://localhost:8004/api/schema/"
},
"output": {
"dir": "local_yaml_client",
"name": "Local YAML API",
"base_url": "http://localhost:8004",
"package_name": "local_yaml_client",
"disable_post_hooks": true
}
}
}
}
```
### Configuration Parameters
#### Global Parameters
| Parameter | Required | Description |
|-----------|----------|-------------|
| `output_dir` | No | Base directory for all generated clients (default: "./clients") |
| `projects` | Yes | Object containing project configurations keyed by project name |
#### Project Input Parameters
| Parameter | Required | Description |
|-----------|----------|-------------|
| `target` | Yes | URL to OpenAPI schema endpoint |
| `prefer_json` | No | If true, prefers JSON format over YAML |
| `params` | No | Query parameters for schema fetch requests |
#### Project Output Parameters
| Parameter | Required | Description |
|-----------|----------|-------------|
| `dir` | Yes | Directory name for generated client |
| `name` | Yes | Human-readable service name |
| `base_url` | No | Service base URL (auto-detected if not provided) |
| `package_name` | No | Python package name (auto-generated if not provided) |
| `disable_post_hooks` | No | Disable post-generation hooks (default: true) |
## Usage in Code
```python
# Import the generated client
from clients.user_service.user_service_client import Client
# Initialize client
client = Client(base_url="http://192.168.100.11:8011")
# Use the client
response = client.users.list_users()
user = client.users.get_user(user_id=123)
```
## All Commands
### Basic Commands
```bash
# Show general help
oasist --help
oasist help
# Show command-specific help
oasist help generate
oasist generate --help
# Show version information
oasist --version
# List all services and their generation status
oasist list
# Show detailed information about a service
oasist info <service_name>
```
### Generation Commands
```bash
# Generate client for a specific service
oasist generate <service_name>
# Force regenerate (overwrite existing)
oasist generate <service_name> --force
# Generate clients for all configured services
oasist generate-all
# Generate all with force overwrite
oasist generate-all --force
```
## Project Structure
```
OASist/
├── oasist/ # Main package
│ ├── __init__.py # Package exports and version
│ ├── oasist.py # Single-file generator implementation
│ └── __pycache__/ # Python cache files
├── dist/ # Distribution files (wheels, tarballs)
├── venv/ # Virtual environment
├── oasist_config.json # Configuration file
├── example.oasist_config.json # Example configuration
├── pyproject.toml # Project configuration
├── requirements.txt # Dependencies
├── README.md # This file
└── test/ # Generated clients directory (configurable)
├── user_service/ # Generated client example
│ ├── pyproject.toml
│ └── user_service_client/
│ ├── __init__.py
│ ├── client.py
│ ├── api/
│ ├── models/
│ └── types.py
└── [other_services]/ # Additional generated clients
```
## Requirements
- Python 3.8+
- openapi-python-client
- requests
- pyyaml
## Troubleshooting
### Schema URL not accessible
Ensure the service is running and the schema endpoint is correct:
```bash
curl http://192.168.100.11:8011/api/schema/
```
### Permission errors
Ensure write permissions for the clients directory:
```bash
chmod -R u+w clients/
```
### Client generation fails
Check if openapi-python-client is installed:
```bash
pip install --upgrade openapi-python-client
```
Enable debug logging in code:
```python
logging.basicConfig(level=logging.DEBUG)
```
## Design Patterns Used
- **Factory Pattern**: `ClientGenerator` creates and manages client generation
- **Command Pattern**: CLI commands encapsulate different operations
- **Dataclass Pattern**: Immutable `ServiceConfig` objects
- **Builder Pattern**: Progressive configuration building
## Django Integration (Optional)
To use with Django management commands:
```python
# In your Django management command
from oasist import ClientGenerator, ServiceConfig
generator = ClientGenerator(output_base=Path("./clients"))
generator.add_service("user", ServiceConfig(...))
generator.generate("user")
```
## Advanced Usage
### Programmatic Usage
```python
from oasist import ClientGenerator, ServiceConfig
from pathlib import Path
# Create generator with custom output directory
generator = ClientGenerator(output_base=Path("./my_clients"))
# Add services
generator.add_service("api", ServiceConfig(
name="API Service",
schema_url="https://api.example.com/openapi.json",
output_dir="api_client",
disable_post_hooks=True
))
# Generate
generator.generate("api", force=True)
# Or generate all
generator.generate_all(force=True)
# Note: You can also modify the OUTPUT_DIR constant at the top of the file
# for persistent changes instead of passing output_base parameter
```
### Custom Base URL
```python
generator.add_service("prod", ServiceConfig(
name="Production API",
schema_url="https://api.example.com/openapi.json",
output_dir="prod_client",
base_url="https://api.example.com", # Custom base URL
disable_post_hooks=True
))
```
## Examples
### Example 1: Generate User Service Client
```bash
$ oasist generate user_service
INFO: ✓ Generated client: user_service → test/user_service
```
### Example 2: List All Services
```bash
$ oasist list
📋 Configured Services:
○ user_service User Service http://localhost:8001/openapi.json
○ communication_service Communication Service http://localhost:8002/openapi.json
○ local_yaml Local YAML API http://localhost:8004/api/schema/
```
### Example 3: Service Information
```bash
$ oasist info user_service
📦 Service: user_service
Name: User Service
Schema URL: http://localhost:8001/openapi.json
Output: test/user_service
Status: Not generated
```
## Contributing
This is a single-file tool designed for simplicity. To extend:
1. Add services in the `main()` function
2. Modify `ClientGenerator` class for custom behavior
3. Add new commands in the command handling section
## License
MIT License - Part of the project
## Support
For issues or questions:
- Check the Troubleshooting section
- Review the OpenAPI schema URL accessibility
- Verify all dependencies are installed
- Enable debug logging for detailed error information
Raw data
{
"_id": null,
"home_page": null,
"name": "oasist",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.8",
"maintainer_email": null,
"keywords": "openapi, client, generator, oas, oasist",
"author": null,
"author_email": "AH Esmaeili <ah.esmaeili.79@gmail.com>",
"download_url": "https://files.pythonhosted.org/packages/93/a6/960d4d04606c2f31e7080e19179553766a8f2fff070bfb487ab0b06cd5af/oasist-1.0.0.tar.gz",
"platform": null,
"description": "# OASist Client Generator\r\n\r\nGenerate type-safe Python clients from OpenAPI schemas with a beautiful CLI interface. Supports both JSON and YAML schemas with Orval-inspired configuration.\r\n\r\n## Features\r\n\r\n- \ud83d\ude80 Single-file implementation with rich CLI interface\r\n- \ud83d\udce6 Generate type-safe Python clients from OpenAPI specs (JSON/YAML)\r\n- \ud83d\udd04 Schema sanitization and validation\r\n- \ud83c\udfaf Orval-inspired configuration format\r\n- \ud83c\udfd7\ufe0f Built with design patterns (Factory, Command, Dataclass)\r\n- \u26a1 Automatic base URL injection and post-hook management\r\n- \ud83c\udfa8 Beautiful terminal UI with progress indicators\r\n\r\n## Installation\r\n\r\n```bash\r\n# Install from PyPI\r\npip install oasist\r\n```\r\n\r\n## Quick Start\r\n\r\n```bash\r\n# List all configured services\r\noasist list\r\n\r\n# Generate a specific client\r\noasist generate user\r\n\r\n# Generate all clients\r\noasist generate-all\r\n\r\n# Show service details\r\noasist info user\r\n\r\n# Force regenerate existing client\r\noasist generate user --force\r\n```\r\n\r\n## Configuration\r\n\r\n### Configuration\r\n\r\nThe generator supports both JSON and YAML OpenAPI documents. It pre-fetches the schema with optional headers/params, then generates via a local temp file to ensure consistent handling of JSON and YAML. Configuration is provided via a single JSON file using an Orval-inspired \"projects\" structure.\r\n\r\nCreate `oasist_config.json` in your project root:\r\n\r\n```json\r\n{\r\n \"output_dir\": \"./test\",\r\n \"projects\": {\r\n \"user_service\": {\r\n \"input\": {\r\n \"target\": \"http://localhost:8001/openapi.json\",\r\n \"prefer_json\": true\r\n },\r\n \"output\": {\r\n \"dir\": \"user_service\",\r\n \"name\": \"User Service\",\r\n \"base_url\": \"http://localhost:8001\",\r\n \"package_name\": \"user_service\",\r\n \"disable_post_hooks\": true\r\n }\r\n },\r\n \"communication_service\": {\r\n \"input\": {\r\n \"target\": \"http://localhost:8002/openapi.json\"\r\n },\r\n \"output\": {\r\n \"dir\": \"communication_service\",\r\n \"name\": \"Communication Service\",\r\n \"base_url\": \"http://localhost:8002\",\r\n \"package_name\": \"communication_service\",\r\n \"disable_post_hooks\": true\r\n }\r\n },\r\n \"local_yaml\": {\r\n \"input\": {\r\n \"target\": \"http://localhost:8004/api/schema/\"\r\n },\r\n \"output\": {\r\n \"dir\": \"local_yaml_client\",\r\n \"name\": \"Local YAML API\",\r\n \"base_url\": \"http://localhost:8004\",\r\n \"package_name\": \"local_yaml_client\",\r\n \"disable_post_hooks\": true\r\n }\r\n }\r\n }\r\n}\r\n```\r\n\r\n \r\n\r\n### Configuration Parameters\r\n\r\n#### Global Parameters\r\n| Parameter | Required | Description |\r\n|-----------|----------|-------------|\r\n| `output_dir` | No | Base directory for all generated clients (default: \"./clients\") |\r\n| `projects` | Yes | Object containing project configurations keyed by project name |\r\n\r\n#### Project Input Parameters\r\n| Parameter | Required | Description |\r\n|-----------|----------|-------------|\r\n| `target` | Yes | URL to OpenAPI schema endpoint |\r\n| `prefer_json` | No | If true, prefers JSON format over YAML |\r\n| `params` | No | Query parameters for schema fetch requests |\r\n\r\n#### Project Output Parameters\r\n| Parameter | Required | Description |\r\n|-----------|----------|-------------|\r\n| `dir` | Yes | Directory name for generated client |\r\n| `name` | Yes | Human-readable service name |\r\n| `base_url` | No | Service base URL (auto-detected if not provided) |\r\n| `package_name` | No | Python package name (auto-generated if not provided) |\r\n| `disable_post_hooks` | No | Disable post-generation hooks (default: true) |\r\n\r\n## Usage in Code\r\n\r\n```python\r\n# Import the generated client\r\nfrom clients.user_service.user_service_client import Client\r\n\r\n# Initialize client\r\nclient = Client(base_url=\"http://192.168.100.11:8011\")\r\n\r\n# Use the client\r\nresponse = client.users.list_users()\r\nuser = client.users.get_user(user_id=123)\r\n```\r\n\r\n## All Commands\r\n\r\n### Basic Commands\r\n\r\n```bash\r\n# Show general help\r\noasist --help\r\noasist help\r\n\r\n# Show command-specific help\r\noasist help generate\r\noasist generate --help\r\n\r\n# Show version information\r\noasist --version\r\n\r\n# List all services and their generation status\r\noasist list\r\n\r\n# Show detailed information about a service\r\noasist info <service_name>\r\n```\r\n\r\n### Generation Commands\r\n\r\n```bash\r\n# Generate client for a specific service\r\noasist generate <service_name>\r\n\r\n# Force regenerate (overwrite existing)\r\noasist generate <service_name> --force\r\n\r\n# Generate clients for all configured services\r\noasist generate-all\r\n\r\n# Generate all with force overwrite\r\noasist generate-all --force\r\n```\r\n\r\n## Project Structure\r\n\r\n```\r\nOASist/\r\n\u251c\u2500\u2500 oasist/ # Main package\r\n\u2502 \u251c\u2500\u2500 __init__.py # Package exports and version\r\n\u2502 \u251c\u2500\u2500 oasist.py # Single-file generator implementation\r\n\u2502 \u2514\u2500\u2500 __pycache__/ # Python cache files\r\n\u251c\u2500\u2500 dist/ # Distribution files (wheels, tarballs)\r\n\u251c\u2500\u2500 venv/ # Virtual environment\r\n\u251c\u2500\u2500 oasist_config.json # Configuration file\r\n\u251c\u2500\u2500 example.oasist_config.json # Example configuration\r\n\u251c\u2500\u2500 pyproject.toml # Project configuration\r\n\u251c\u2500\u2500 requirements.txt # Dependencies\r\n\u251c\u2500\u2500 README.md # This file\r\n\u2514\u2500\u2500 test/ # Generated clients directory (configurable)\r\n \u251c\u2500\u2500 user_service/ # Generated client example\r\n \u2502 \u251c\u2500\u2500 pyproject.toml\r\n \u2502 \u2514\u2500\u2500 user_service_client/\r\n \u2502 \u251c\u2500\u2500 __init__.py\r\n \u2502 \u251c\u2500\u2500 client.py\r\n \u2502 \u251c\u2500\u2500 api/\r\n \u2502 \u251c\u2500\u2500 models/\r\n \u2502 \u2514\u2500\u2500 types.py\r\n \u2514\u2500\u2500 [other_services]/ # Additional generated clients\r\n```\r\n\r\n## Requirements\r\n\r\n- Python 3.8+\r\n- openapi-python-client\r\n- requests\r\n- pyyaml\r\n\r\n## Troubleshooting\r\n\r\n### Schema URL not accessible\r\nEnsure the service is running and the schema endpoint is correct:\r\n```bash\r\ncurl http://192.168.100.11:8011/api/schema/\r\n```\r\n\r\n### Permission errors\r\nEnsure write permissions for the clients directory:\r\n```bash\r\nchmod -R u+w clients/\r\n```\r\n\r\n### Client generation fails\r\nCheck if openapi-python-client is installed:\r\n```bash\r\npip install --upgrade openapi-python-client\r\n```\r\n\r\nEnable debug logging in code:\r\n```python\r\nlogging.basicConfig(level=logging.DEBUG)\r\n```\r\n\r\n## Design Patterns Used\r\n\r\n- **Factory Pattern**: `ClientGenerator` creates and manages client generation\r\n- **Command Pattern**: CLI commands encapsulate different operations\r\n- **Dataclass Pattern**: Immutable `ServiceConfig` objects\r\n- **Builder Pattern**: Progressive configuration building\r\n\r\n## Django Integration (Optional)\r\n\r\nTo use with Django management commands:\r\n\r\n```python\r\n# In your Django management command\r\nfrom oasist import ClientGenerator, ServiceConfig\r\n\r\ngenerator = ClientGenerator(output_base=Path(\"./clients\"))\r\ngenerator.add_service(\"user\", ServiceConfig(...))\r\ngenerator.generate(\"user\")\r\n```\r\n\r\n## Advanced Usage\r\n\r\n### Programmatic Usage\r\n\r\n```python\r\nfrom oasist import ClientGenerator, ServiceConfig\r\nfrom pathlib import Path\r\n\r\n# Create generator with custom output directory\r\ngenerator = ClientGenerator(output_base=Path(\"./my_clients\"))\r\n\r\n# Add services\r\ngenerator.add_service(\"api\", ServiceConfig(\r\n name=\"API Service\",\r\n schema_url=\"https://api.example.com/openapi.json\",\r\n output_dir=\"api_client\",\r\n disable_post_hooks=True\r\n))\r\n\r\n# Generate\r\ngenerator.generate(\"api\", force=True)\r\n\r\n# Or generate all\r\ngenerator.generate_all(force=True)\r\n\r\n# Note: You can also modify the OUTPUT_DIR constant at the top of the file\r\n# for persistent changes instead of passing output_base parameter\r\n```\r\n\r\n### Custom Base URL\r\n\r\n```python\r\ngenerator.add_service(\"prod\", ServiceConfig(\r\n name=\"Production API\",\r\n schema_url=\"https://api.example.com/openapi.json\",\r\n output_dir=\"prod_client\",\r\n base_url=\"https://api.example.com\", # Custom base URL\r\n disable_post_hooks=True\r\n))\r\n```\r\n\r\n## Examples\r\n\r\n### Example 1: Generate User Service Client\r\n\r\n```bash\r\n$ oasist generate user_service\r\nINFO: \u2713 Generated client: user_service \u2192 test/user_service\r\n```\r\n\r\n### Example 2: List All Services\r\n\r\n```bash\r\n$ oasist list\r\n\r\n\ud83d\udccb Configured Services:\r\n \u25cb user_service User Service http://localhost:8001/openapi.json\r\n \u25cb communication_service Communication Service http://localhost:8002/openapi.json\r\n \u25cb local_yaml Local YAML API http://localhost:8004/api/schema/\r\n```\r\n\r\n### Example 3: Service Information\r\n\r\n```bash\r\n$ oasist info user_service\r\n\r\n\ud83d\udce6 Service: user_service\r\n Name: User Service\r\n Schema URL: http://localhost:8001/openapi.json\r\n Output: test/user_service\r\n Status: Not generated\r\n```\r\n\r\n## Contributing\r\n\r\nThis is a single-file tool designed for simplicity. To extend:\r\n\r\n1. Add services in the `main()` function\r\n2. Modify `ClientGenerator` class for custom behavior\r\n3. Add new commands in the command handling section\r\n\r\n## License\r\n\r\nMIT License - Part of the project\r\n\r\n## Support\r\n\r\nFor issues or questions:\r\n- Check the Troubleshooting section\r\n- Review the OpenAPI schema URL accessibility\r\n- Verify all dependencies are installed\r\n- Enable debug logging for detailed error information\r\n",
"bugtrack_url": null,
"license": "MIT",
"summary": "OASist Client Generator: generate Python clients from OpenAPI schemas",
"version": "1.0.0",
"project_urls": {
"Repository": "https://github.com/AhEsmaeili79/oasist"
},
"split_keywords": [
"openapi",
" client",
" generator",
" oas",
" oasist"
],
"urls": [
{
"comment_text": null,
"digests": {
"blake2b_256": "917748438a7624f0de9f2c67fec6f38321c5b4a45b89c1fe36801297e9d0e27f",
"md5": "f0a3bc3c6c3ab9dd4a4545452d18029e",
"sha256": "8d9b7c2ed7223fe7ca8608d75ace1560bd19e77d7dcd22bcd7825437db495199"
},
"downloads": -1,
"filename": "oasist-1.0.0-py3-none-any.whl",
"has_sig": false,
"md5_digest": "f0a3bc3c6c3ab9dd4a4545452d18029e",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.8",
"size": 12312,
"upload_time": "2025-10-06T18:23:49",
"upload_time_iso_8601": "2025-10-06T18:23:49.726368Z",
"url": "https://files.pythonhosted.org/packages/91/77/48438a7624f0de9f2c67fec6f38321c5b4a45b89c1fe36801297e9d0e27f/oasist-1.0.0-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "93a6960d4d04606c2f31e7080e19179553766a8f2fff070bfb487ab0b06cd5af",
"md5": "647d60e35f0bf8db20a14e53098d136e",
"sha256": "bcf91e5ff06d92bb3fda7868dda77c482aa819b4643ee7009b5c62fe8bde4a74"
},
"downloads": -1,
"filename": "oasist-1.0.0.tar.gz",
"has_sig": false,
"md5_digest": "647d60e35f0bf8db20a14e53098d136e",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.8",
"size": 15675,
"upload_time": "2025-10-06T18:23:57",
"upload_time_iso_8601": "2025-10-06T18:23:57.275431Z",
"url": "https://files.pythonhosted.org/packages/93/a6/960d4d04606c2f31e7080e19179553766a8f2fff070bfb487ab0b06cd5af/oasist-1.0.0.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2025-10-06 18:23:57",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "AhEsmaeili79",
"github_project": "oasist",
"travis_ci": false,
"coveralls": false,
"github_actions": false,
"requirements": [
{
"name": "openapi-python-client",
"specs": [
[
"==",
"0.26.1"
]
]
},
{
"name": "requests",
"specs": [
[
">=",
"2.31.0"
]
]
},
{
"name": "pyyaml",
"specs": [
[
">=",
"6.0.1"
]
]
},
{
"name": "rich",
"specs": [
[
">=",
"13.7.0"
]
]
}
],
"lcname": "oasist"
}