mockstack 0.6.1__tar.gz → 0.7.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- mockstack-0.7.1/.dockerignore +18 -0
- mockstack-0.7.1/.github/workflows/publish-to-dockerhub.yml +53 -0
- mockstack-0.7.1/Dockerfile +72 -0
- {mockstack-0.6.1/mockstack.egg-info → mockstack-0.7.1}/PKG-INFO +9 -7
- {mockstack-0.6.1 → mockstack-0.7.1}/README.md +8 -6
- mockstack-0.7.1/docker-entrypoint.sh +8 -0
- {mockstack-0.6.1 → mockstack-0.7.1}/examples/llm/mockstack-langchain-example.ipynb +46 -1
- mockstack-0.7.1/examples/llm/templates/openai-v1-deployments-gpt-4o-chat-completions.j2 +35 -0
- {mockstack-0.6.1 → mockstack-0.7.1}/mockstack/display.py +4 -1
- {mockstack-0.6.1 → mockstack-0.7.1/mockstack.egg-info}/PKG-INFO +9 -7
- {mockstack-0.6.1 → mockstack-0.7.1}/mockstack.egg-info/SOURCES.txt +5 -0
- {mockstack-0.6.1 → mockstack-0.7.1}/.env.example +0 -0
- {mockstack-0.6.1 → mockstack-0.7.1}/.github/workflows/ci.yml +0 -0
- {mockstack-0.6.1 → mockstack-0.7.1}/.github/workflows/publish-docs.yml +0 -0
- {mockstack-0.6.1 → mockstack-0.7.1}/.github/workflows/publish-to-pypi.yml +0 -0
- {mockstack-0.6.1 → mockstack-0.7.1}/.gitignore +0 -0
- {mockstack-0.6.1 → mockstack-0.7.1}/.pre-commit-config.yaml +0 -0
- {mockstack-0.6.1 → mockstack-0.7.1}/CODE_OF_CONDUCT.md +0 -0
- {mockstack-0.6.1 → mockstack-0.7.1}/LICENSE +0 -0
- {mockstack-0.6.1 → mockstack-0.7.1}/SECURITY.md +0 -0
- {mockstack-0.6.1 → mockstack-0.7.1}/docs/assets/favicon.ico +0 -0
- {mockstack-0.6.1 → mockstack-0.7.1}/docs/assets/logo.png +0 -0
- {mockstack-0.6.1 → mockstack-0.7.1}/docs/assets/mockstack.png +0 -0
- {mockstack-0.6.1 → mockstack-0.7.1}/docs/configuration.md +0 -0
- {mockstack-0.6.1 → mockstack-0.7.1}/docs/strategies/base.md +0 -0
- {mockstack-0.6.1 → mockstack-0.7.1}/docs/strategies/filefixtures.md +0 -0
- {mockstack-0.6.1 → mockstack-0.7.1}/docs/strategies/proxyrules.md +0 -0
- {mockstack-0.6.1 → mockstack-0.7.1}/examples/filefixtures-with-templates/.env.example +0 -0
- {mockstack-0.6.1 → mockstack-0.7.1}/examples/filefixtures-with-templates/README.md +0 -0
- {mockstack-0.6.1 → mockstack-0.7.1}/examples/filefixtures-with-templates/templates/servicename-api-v1-items.j2 +0 -0
- {mockstack-0.6.1 → mockstack-0.7.1}/examples/filefixtures-with-templates/templates/servicename2-api-v2-user.533ec889-7c68-45c8-b21e-4a7e455d1234.j2 +0 -0
- {mockstack-0.6.1 → mockstack-0.7.1}/examples/llm/README.md +0 -0
- {mockstack-0.6.1 → mockstack-0.7.1}/examples/llm/templates/openai-v1-chat-completions.j2 +0 -0
- {mockstack-0.6.1 → mockstack-0.7.1}/examples/proxyrules-with-rules-file/.env.example +0 -0
- {mockstack-0.6.1 → mockstack-0.7.1}/examples/proxyrules-with-rules-file/README.md +0 -0
- {mockstack-0.6.1 → mockstack-0.7.1}/examples/proxyrules-with-rules-file/rules.yml +0 -0
- {mockstack-0.6.1 → mockstack-0.7.1}/mkdocs.yml +0 -0
- {mockstack-0.6.1 → mockstack-0.7.1}/mockstack/__init__.py +0 -0
- {mockstack-0.6.1 → mockstack-0.7.1}/mockstack/config.py +0 -0
- {mockstack-0.6.1 → mockstack-0.7.1}/mockstack/constants.py +0 -0
- {mockstack-0.6.1 → mockstack-0.7.1}/mockstack/identifiers.py +0 -0
- {mockstack-0.6.1 → mockstack-0.7.1}/mockstack/intent.py +0 -0
- {mockstack-0.6.1 → mockstack-0.7.1}/mockstack/lifespan.py +0 -0
- {mockstack-0.6.1 → mockstack-0.7.1}/mockstack/main.py +0 -0
- {mockstack-0.6.1 → mockstack-0.7.1}/mockstack/middleware.py +0 -0
- {mockstack-0.6.1 → mockstack-0.7.1}/mockstack/routers/__init__.py +0 -0
- {mockstack-0.6.1 → mockstack-0.7.1}/mockstack/routers/catchall.py +0 -0
- {mockstack-0.6.1 → mockstack-0.7.1}/mockstack/routers/homepage.py +0 -0
- {mockstack-0.6.1 → mockstack-0.7.1}/mockstack/strategies/__init__.py +0 -0
- {mockstack-0.6.1 → mockstack-0.7.1}/mockstack/strategies/base.py +0 -0
- {mockstack-0.6.1 → mockstack-0.7.1}/mockstack/strategies/create_mixin.py +0 -0
- {mockstack-0.6.1 → mockstack-0.7.1}/mockstack/strategies/factory.py +0 -0
- {mockstack-0.6.1 → mockstack-0.7.1}/mockstack/strategies/filefixtures.py +0 -0
- {mockstack-0.6.1 → mockstack-0.7.1}/mockstack/strategies/proxyrules.py +0 -0
- {mockstack-0.6.1 → mockstack-0.7.1}/mockstack/telemetry.py +0 -0
- {mockstack-0.6.1 → mockstack-0.7.1}/mockstack/templating.py +0 -0
- {mockstack-0.6.1 → mockstack-0.7.1}/mockstack/tests/__init__.py +0 -0
- {mockstack-0.6.1 → mockstack-0.7.1}/mockstack/tests/conftest.py +0 -0
- {mockstack-0.6.1 → mockstack-0.7.1}/mockstack/tests/fixtures/proxyrules.yml +0 -0
- {mockstack-0.6.1 → mockstack-0.7.1}/mockstack/tests/fixtures/templates/__init__.py +0 -0
- {mockstack-0.6.1 → mockstack-0.7.1}/mockstack/tests/fixtures/templates/example-template.j2 +0 -0
- {mockstack-0.6.1 → mockstack-0.7.1}/mockstack/tests/routers/__init__.py +0 -0
- {mockstack-0.6.1 → mockstack-0.7.1}/mockstack/tests/routers/test_catchall.py +0 -0
- {mockstack-0.6.1 → mockstack-0.7.1}/mockstack/tests/routers/test_homepage.py +0 -0
- {mockstack-0.6.1 → mockstack-0.7.1}/mockstack/tests/strategies/test_create_mixin.py +0 -0
- {mockstack-0.6.1 → mockstack-0.7.1}/mockstack/tests/strategies/test_filefixtures.py +0 -0
- {mockstack-0.6.1 → mockstack-0.7.1}/mockstack/tests/strategies/test_proxyrules.py +0 -0
- {mockstack-0.6.1 → mockstack-0.7.1}/mockstack/tests/test_display.py +0 -0
- {mockstack-0.6.1 → mockstack-0.7.1}/mockstack/tests/test_identifiers.py +0 -0
- {mockstack-0.6.1 → mockstack-0.7.1}/mockstack/tests/test_middleware.py +0 -0
- {mockstack-0.6.1 → mockstack-0.7.1}/mockstack/tests/test_telemetry.py +0 -0
- {mockstack-0.6.1 → mockstack-0.7.1}/mockstack/tests/test_templating.py +0 -0
- {mockstack-0.6.1 → mockstack-0.7.1}/mockstack.egg-info/dependency_links.txt +0 -0
- {mockstack-0.6.1 → mockstack-0.7.1}/mockstack.egg-info/entry_points.txt +0 -0
- {mockstack-0.6.1 → mockstack-0.7.1}/mockstack.egg-info/requires.txt +0 -0
- {mockstack-0.6.1 → mockstack-0.7.1}/mockstack.egg-info/top_level.txt +0 -0
- {mockstack-0.6.1 → mockstack-0.7.1}/pyproject.toml +0 -0
- {mockstack-0.6.1 → mockstack-0.7.1}/setup.cfg +0 -0
- {mockstack-0.6.1 → mockstack-0.7.1}/uv.lock +0 -0
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
*
|
|
2
|
+
!mockstack
|
|
3
|
+
mockstack/tests
|
|
4
|
+
!dist/*-none-any.whl
|
|
5
|
+
!MANIFEST.in
|
|
6
|
+
!README.md
|
|
7
|
+
!HISTORY.rst
|
|
8
|
+
!requirements*.txt
|
|
9
|
+
!setup.py
|
|
10
|
+
!setup.cfg
|
|
11
|
+
!mypy.ini
|
|
12
|
+
!pyproject.toml
|
|
13
|
+
!conftest.py
|
|
14
|
+
!uv.lock
|
|
15
|
+
!docker-entrypoint.sh
|
|
16
|
+
|
|
17
|
+
**/*.pyc
|
|
18
|
+
**/*~
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
name: Publish Docker image to DockerHub
|
|
2
|
+
|
|
3
|
+
permissions:
|
|
4
|
+
contents: read
|
|
5
|
+
pull-requests: write
|
|
6
|
+
|
|
7
|
+
on:
|
|
8
|
+
push:
|
|
9
|
+
branches:
|
|
10
|
+
- "**"
|
|
11
|
+
tags:
|
|
12
|
+
- "*.*.*"
|
|
13
|
+
pull_request:
|
|
14
|
+
|
|
15
|
+
jobs:
|
|
16
|
+
docker:
|
|
17
|
+
runs-on: ubuntu-latest
|
|
18
|
+
steps:
|
|
19
|
+
- name: Docker meta
|
|
20
|
+
id: meta
|
|
21
|
+
uses: docker/metadata-action@v5
|
|
22
|
+
with:
|
|
23
|
+
# list of Docker images to use as base name for tags
|
|
24
|
+
images: |
|
|
25
|
+
mockstack/mockstack
|
|
26
|
+
# generate Docker tags based on the following events/attributes
|
|
27
|
+
tags: |
|
|
28
|
+
type=ref,event=branch
|
|
29
|
+
type=ref,event=pr
|
|
30
|
+
type=semver,pattern={{version}}
|
|
31
|
+
type=semver,pattern={{major}}.{{minor}}
|
|
32
|
+
type=semver,pattern={{major}}
|
|
33
|
+
type=sha
|
|
34
|
+
|
|
35
|
+
- name: Login to Docker Hub
|
|
36
|
+
if: github.event_name != 'pull_request'
|
|
37
|
+
uses: docker/login-action@v3
|
|
38
|
+
with:
|
|
39
|
+
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
|
40
|
+
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
|
41
|
+
|
|
42
|
+
- name: Set up QEMU
|
|
43
|
+
uses: docker/setup-qemu-action@v3
|
|
44
|
+
|
|
45
|
+
- name: Set up Docker Buildx
|
|
46
|
+
uses: docker/setup-buildx-action@v3
|
|
47
|
+
|
|
48
|
+
- name: Build and push
|
|
49
|
+
uses: docker/build-push-action@v6
|
|
50
|
+
with:
|
|
51
|
+
push: ${{ github.event_name != 'pull_request' }}
|
|
52
|
+
tags: ${{ steps.meta.outputs.tags }}
|
|
53
|
+
labels: ${{ steps.meta.outputs.labels }}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
# ---------------------------- Build Time Arguments ----------------------------
|
|
2
|
+
|
|
3
|
+
# Define build argument for version
|
|
4
|
+
ARG PYTHON_IMAGE_VERSION=3.13.3-slim
|
|
5
|
+
ARG MOCKSTACK_VERSION=0.1.0
|
|
6
|
+
|
|
7
|
+
# ---------------------------- Base Image --------------------------------
|
|
8
|
+
|
|
9
|
+
FROM python:${PYTHON_IMAGE_VERSION} AS base
|
|
10
|
+
|
|
11
|
+
# Install system dependencies
|
|
12
|
+
RUN apt-get update && apt-get install --no-install-recommends -y \
|
|
13
|
+
curl \
|
|
14
|
+
git \
|
|
15
|
+
&& rm -rf /var/lib/apt/lists/*
|
|
16
|
+
|
|
17
|
+
# Install uv and add it to PATH
|
|
18
|
+
ENV PATH="/root/.local/bin:${PATH}"
|
|
19
|
+
SHELL ["/bin/bash", "-o", "pipefail", "-c"]
|
|
20
|
+
RUN curl -LsSf https://astral.sh/uv/install.sh | sh
|
|
21
|
+
|
|
22
|
+
# ---------------------------- Builder --------------------------------
|
|
23
|
+
|
|
24
|
+
FROM base AS builder
|
|
25
|
+
|
|
26
|
+
ARG MOCKSTACK_VERSION
|
|
27
|
+
|
|
28
|
+
# Maintainer label
|
|
29
|
+
LABEL maintainer="mockstack.contact@gmail.com"
|
|
30
|
+
|
|
31
|
+
# Set working directory
|
|
32
|
+
WORKDIR /app
|
|
33
|
+
|
|
34
|
+
# Create package structure
|
|
35
|
+
RUN mkdir -p /app/src/mockstack /usr/local/share/mockstack/templates
|
|
36
|
+
|
|
37
|
+
# Copy package files
|
|
38
|
+
COPY mockstack /app/src/mockstack/
|
|
39
|
+
COPY docker-entrypoint.sh pyproject.toml setup.* README.md /app/
|
|
40
|
+
|
|
41
|
+
WORKDIR /app
|
|
42
|
+
|
|
43
|
+
# Set version using build argument. Needs to happen before
|
|
44
|
+
# we install the package with `pip install -e` below.
|
|
45
|
+
ENV SETUPTOOLS_SCM_PRETEND_VERSION=${MOCKSTACK_VERSION}
|
|
46
|
+
|
|
47
|
+
# Create and activate virtual environment, then install dependencies
|
|
48
|
+
RUN uv venv && \
|
|
49
|
+
. .venv/bin/activate
|
|
50
|
+
|
|
51
|
+
RUN uv pip install -e .
|
|
52
|
+
|
|
53
|
+
# ---------------------------- Runner --------------------------------
|
|
54
|
+
|
|
55
|
+
FROM builder AS runner
|
|
56
|
+
|
|
57
|
+
# Set required environment variables for virtualenv
|
|
58
|
+
ENV VIRTUAL_ENV="/app/.venv"
|
|
59
|
+
ENV PATH="/app/.venv/bin:$PATH"
|
|
60
|
+
|
|
61
|
+
# Set default
|
|
62
|
+
ENV MOCKSTACK__TEMPLATES_DIR=/usr/local/share/mockstack/templates
|
|
63
|
+
|
|
64
|
+
# Create a sample template file for default running of mockstack
|
|
65
|
+
RUN echo '{"message": "Hello from mockstack!"}' > /usr/local/share/mockstack/templates/index.j2
|
|
66
|
+
|
|
67
|
+
# Expose the default port
|
|
68
|
+
EXPOSE 8000
|
|
69
|
+
|
|
70
|
+
# Set the entrypoint to run the mockstack service
|
|
71
|
+
ENTRYPOINT ["/app/docker-entrypoint.sh"]
|
|
72
|
+
CMD ["uv", "run", "mockstack"]
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: mockstack
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.7.1
|
|
4
4
|
Summary: An API mocking workhorse
|
|
5
5
|
Author-email: Adam Ever-Hadani <mockstack.contact@gmail.com>
|
|
6
6
|
License-Expression: MIT
|
|
@@ -37,6 +37,8 @@ Dynamic: license-file
|
|
|
37
37
|
[](https://github.com/adamhadani/mockstack/actions/workflows/ci.yml)
|
|
38
38
|
[](https://github.com/adamhadani/mockstack/blob/main/LICENSE)
|
|
39
39
|
[](https://pypi.org/project/mockstack/)
|
|
40
|
+
[](https://pypi.org/project/mockstack/)
|
|
41
|
+
|
|
40
42
|
|
|
41
43
|
An API mocking workhorse :racehorse:
|
|
42
44
|
|
|
@@ -48,21 +50,21 @@ Use mockstack for:
|
|
|
48
50
|
|
|
49
51
|
* **Integration Testing** :ok_hand:. Creating a consistent environment for running integration tests on a single component, using fixture responses.
|
|
50
52
|
|
|
51
|
-
* **LLM-powered Workflows** :alien:. Speeding up development of LLM-based workflows and tools for use with frameworks such as [LangChain](https://python.langchain.com/docs/introduction/), [LangGraph](https://www.langchain.com/langgraph) and others. When developing LLM-driven execution graphs, you often want to have a consistent response from a tool while you're tuning prompts or debugging other aspects of a particular trace.
|
|
53
|
+
* **LLM-powered Workflows** :alien:. Speeding up development of LLM-based workflows and tools for use with frameworks such as [LangChain](https://python.langchain.com/docs/introduction/), [LangGraph](https://www.langchain.com/langgraph) and others. When developing LLM-driven execution graphs, you often want to have a consistent response from a tool while you're tuning prompts or debugging other aspects of a particular trace. **mockstack** can give you a solid foundation for this.
|
|
52
54
|
|
|
53
|
-
* **Chaos Engineering** :boom:. mockstack can simulate various real-world runtime error scenarios such as timeouts, http error codes, and invalid response payloads. This can be a great way to do some upfront
|
|
55
|
+
* **Chaos Engineering** :boom:. mockstack can simulate various real-world runtime error scenarios such as timeouts, http error codes, and invalid response payloads. This can be a great way to do some upfront [Chaos Monkey](https://github.com/Netflix/chaosmonkey) type of testing on software components.
|
|
54
56
|
|
|
55
57
|
Highlights include:
|
|
56
58
|
|
|
57
|
-
* Multiple strategies for handling requests such as
|
|
58
|
-
* Observability via OpenTelemetry integration. Get detailed traces of your sessions instantly reported to backends such as Grafana, Jaeger, Zipkin, etc. :eyes:
|
|
59
|
-
* Configurability via
|
|
59
|
+
* Multiple strategies for handling requests such as [Jinja](https://jinja.palletsprojects.com/en/stable/) template files with intelligent URL request-to-template routing, proxy strategy, and mixed strategies. :game_die:
|
|
60
|
+
* Observability via [OpenTelemetry](https://opentelemetry.io/) integration. Get detailed traces of your sessions instantly reported to backends such as [Grafana](https://grafana.com/), [Jaeger](https://www.jaegertracing.io/), [Zipkin](https://zipkin.io/), etc. :eyes:
|
|
61
|
+
* Configurability via [pydantic-settings](https://docs.pydantic.dev/latest/concepts/pydantic_settings/) supports customizing behaviour via environment variables and a `.env` file. :flags:
|
|
60
62
|
* Comprehensive unit-tests, linting and formatting coverage as well as vulnerabilities and security scanning with full CI automation to ensure stability and a high-quality codebase for production-grade use. :+1:
|
|
61
63
|
|
|
62
64
|
|
|
63
65
|
## Installation
|
|
64
66
|
|
|
65
|
-
Install using [uv](https://docs.astral.sh/uv/). This package conforms the concept of a [tool](https://docs.astral.sh/uv/concepts/tools/) and hence can simply install / run with
|
|
67
|
+
Install using [uv](https://docs.astral.sh/uv/). This package conforms the concept of a [tool](https://docs.astral.sh/uv/concepts/tools/) and hence can simply install / run with [uvx](https://docs.astral.sh/uv/guides/tools/):
|
|
66
68
|
|
|
67
69
|
uvx mockstack --help
|
|
68
70
|
|
|
@@ -6,6 +6,8 @@
|
|
|
6
6
|
[](https://github.com/adamhadani/mockstack/actions/workflows/ci.yml)
|
|
7
7
|
[](https://github.com/adamhadani/mockstack/blob/main/LICENSE)
|
|
8
8
|
[](https://pypi.org/project/mockstack/)
|
|
9
|
+
[](https://pypi.org/project/mockstack/)
|
|
10
|
+
|
|
9
11
|
|
|
10
12
|
An API mocking workhorse :racehorse:
|
|
11
13
|
|
|
@@ -17,21 +19,21 @@ Use mockstack for:
|
|
|
17
19
|
|
|
18
20
|
* **Integration Testing** :ok_hand:. Creating a consistent environment for running integration tests on a single component, using fixture responses.
|
|
19
21
|
|
|
20
|
-
* **LLM-powered Workflows** :alien:. Speeding up development of LLM-based workflows and tools for use with frameworks such as [LangChain](https://python.langchain.com/docs/introduction/), [LangGraph](https://www.langchain.com/langgraph) and others. When developing LLM-driven execution graphs, you often want to have a consistent response from a tool while you're tuning prompts or debugging other aspects of a particular trace.
|
|
22
|
+
* **LLM-powered Workflows** :alien:. Speeding up development of LLM-based workflows and tools for use with frameworks such as [LangChain](https://python.langchain.com/docs/introduction/), [LangGraph](https://www.langchain.com/langgraph) and others. When developing LLM-driven execution graphs, you often want to have a consistent response from a tool while you're tuning prompts or debugging other aspects of a particular trace. **mockstack** can give you a solid foundation for this.
|
|
21
23
|
|
|
22
|
-
* **Chaos Engineering** :boom:. mockstack can simulate various real-world runtime error scenarios such as timeouts, http error codes, and invalid response payloads. This can be a great way to do some upfront
|
|
24
|
+
* **Chaos Engineering** :boom:. mockstack can simulate various real-world runtime error scenarios such as timeouts, http error codes, and invalid response payloads. This can be a great way to do some upfront [Chaos Monkey](https://github.com/Netflix/chaosmonkey) type of testing on software components.
|
|
23
25
|
|
|
24
26
|
Highlights include:
|
|
25
27
|
|
|
26
|
-
* Multiple strategies for handling requests such as
|
|
27
|
-
* Observability via OpenTelemetry integration. Get detailed traces of your sessions instantly reported to backends such as Grafana, Jaeger, Zipkin, etc. :eyes:
|
|
28
|
-
* Configurability via
|
|
28
|
+
* Multiple strategies for handling requests such as [Jinja](https://jinja.palletsprojects.com/en/stable/) template files with intelligent URL request-to-template routing, proxy strategy, and mixed strategies. :game_die:
|
|
29
|
+
* Observability via [OpenTelemetry](https://opentelemetry.io/) integration. Get detailed traces of your sessions instantly reported to backends such as [Grafana](https://grafana.com/), [Jaeger](https://www.jaegertracing.io/), [Zipkin](https://zipkin.io/), etc. :eyes:
|
|
30
|
+
* Configurability via [pydantic-settings](https://docs.pydantic.dev/latest/concepts/pydantic_settings/) supports customizing behaviour via environment variables and a `.env` file. :flags:
|
|
29
31
|
* Comprehensive unit-tests, linting and formatting coverage as well as vulnerabilities and security scanning with full CI automation to ensure stability and a high-quality codebase for production-grade use. :+1:
|
|
30
32
|
|
|
31
33
|
|
|
32
34
|
## Installation
|
|
33
35
|
|
|
34
|
-
Install using [uv](https://docs.astral.sh/uv/). This package conforms the concept of a [tool](https://docs.astral.sh/uv/concepts/tools/) and hence can simply install / run with
|
|
36
|
+
Install using [uv](https://docs.astral.sh/uv/). This package conforms the concept of a [tool](https://docs.astral.sh/uv/concepts/tools/) and hence can simply install / run with [uvx](https://docs.astral.sh/uv/guides/tools/):
|
|
35
37
|
|
|
36
38
|
uvx mockstack --help
|
|
37
39
|
|
|
@@ -42,7 +42,7 @@
|
|
|
42
42
|
},
|
|
43
43
|
{
|
|
44
44
|
"cell_type": "code",
|
|
45
|
-
"execution_count":
|
|
45
|
+
"execution_count": 38,
|
|
46
46
|
"metadata": {},
|
|
47
47
|
"outputs": [],
|
|
48
48
|
"source": [
|
|
@@ -71,6 +71,51 @@
|
|
|
71
71
|
"assert ai_msg.content == \"Hello! How can I assist you today?\""
|
|
72
72
|
]
|
|
73
73
|
},
|
|
74
|
+
{
|
|
75
|
+
"cell_type": "markdown",
|
|
76
|
+
"metadata": {},
|
|
77
|
+
"source": [
|
|
78
|
+
"Below is an identical example, but using OpenAI via Microsoft Azure.\n",
|
|
79
|
+
"\n",
|
|
80
|
+
"The only difference is that under the hood `LangChain` will hit an API URL of the form `/openai/v1/deployments/gpt-4o/chat/completions?api-version=<api-version>`.\n",
|
|
81
|
+
"\n",
|
|
82
|
+
"We can again handle this easily using templates by just creating a file with the name `openai-v1-deployments-gpt-4o-chat-completions.j2`.\n",
|
|
83
|
+
"\n",
|
|
84
|
+
"Remember you can also create conditional logic inside that file using Jinja syntax to return different mock responses depending on the request parameters, for instance using the query parameter `api-version`."
|
|
85
|
+
]
|
|
86
|
+
},
|
|
87
|
+
{
|
|
88
|
+
"cell_type": "code",
|
|
89
|
+
"execution_count": 40,
|
|
90
|
+
"metadata": {},
|
|
91
|
+
"outputs": [],
|
|
92
|
+
"source": [
|
|
93
|
+
"from langchain_openai import AzureChatOpenAI\n",
|
|
94
|
+
"\n",
|
|
95
|
+
"\n",
|
|
96
|
+
"llm = AzureChatOpenAI(\n",
|
|
97
|
+
" model=\"gpt-4o\",\n",
|
|
98
|
+
" api_version=\"2024-02-15-preview\",\n",
|
|
99
|
+
" temperature=0,\n",
|
|
100
|
+
" max_tokens=None,\n",
|
|
101
|
+
" timeout=None,\n",
|
|
102
|
+
" max_retries=2,\n",
|
|
103
|
+
" base_url=\"http://localhost:8000/openai/v1\",\n",
|
|
104
|
+
" api_key=\"SOME_STRING_THAT_DOES_NOT_MATTER\",\n",
|
|
105
|
+
")\n",
|
|
106
|
+
"\n",
|
|
107
|
+
"messages = [\n",
|
|
108
|
+
" (\n",
|
|
109
|
+
" \"system\",\n",
|
|
110
|
+
" \"You are a helpful assistant that translates English to French. Translate the user sentence.\",\n",
|
|
111
|
+
" ),\n",
|
|
112
|
+
" (\"human\", \"I love programming.\"),\n",
|
|
113
|
+
"]\n",
|
|
114
|
+
"ai_msg = llm.invoke(messages)\n",
|
|
115
|
+
"\n",
|
|
116
|
+
"assert ai_msg.content == \"Hello! How can I assist you today?\""
|
|
117
|
+
]
|
|
118
|
+
},
|
|
74
119
|
{
|
|
75
120
|
"cell_type": "markdown",
|
|
76
121
|
"metadata": {},
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
{
|
|
2
|
+
"id": "chatcmpl-B9MBs8CjcvOU2jLn4n570S5qMJKcT",
|
|
3
|
+
"object": "chat.completion",
|
|
4
|
+
"created": 1741569952,
|
|
5
|
+
"model": "gpt-4.1-2025-04-14",
|
|
6
|
+
"choices": [
|
|
7
|
+
{
|
|
8
|
+
"index": 0,
|
|
9
|
+
"message": {
|
|
10
|
+
"role": "assistant",
|
|
11
|
+
"content": "Hello! How can I assist you today?",
|
|
12
|
+
"refusal": null,
|
|
13
|
+
"annotations": []
|
|
14
|
+
},
|
|
15
|
+
"logprobs": null,
|
|
16
|
+
"finish_reason": "stop"
|
|
17
|
+
}
|
|
18
|
+
],
|
|
19
|
+
"usage": {
|
|
20
|
+
"prompt_tokens": 19,
|
|
21
|
+
"completion_tokens": 10,
|
|
22
|
+
"total_tokens": 29,
|
|
23
|
+
"prompt_tokens_details": {
|
|
24
|
+
"cached_tokens": 0,
|
|
25
|
+
"audio_tokens": 0
|
|
26
|
+
},
|
|
27
|
+
"completion_tokens_details": {
|
|
28
|
+
"reasoning_tokens": 0,
|
|
29
|
+
"audio_tokens": 0,
|
|
30
|
+
"accepted_prediction_tokens": 0,
|
|
31
|
+
"rejected_prediction_tokens": 0
|
|
32
|
+
}
|
|
33
|
+
},
|
|
34
|
+
"service_tier": "default"
|
|
35
|
+
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"""Display and logging functionality."""
|
|
2
2
|
|
|
3
3
|
import logging
|
|
4
|
+
from importlib import metadata
|
|
4
5
|
|
|
5
6
|
from fastapi import FastAPI
|
|
6
7
|
|
|
@@ -12,8 +13,10 @@ def announce(app: FastAPI, settings: Settings):
|
|
|
12
13
|
logger = logging.getLogger("uvicorn")
|
|
13
14
|
extra = {"markup": True}
|
|
14
15
|
|
|
16
|
+
version = metadata.version("mockstack")
|
|
17
|
+
|
|
15
18
|
logger.info(
|
|
16
|
-
f"[bold medium_purple]mockstack[/bold medium_purple] ready to roll. "
|
|
19
|
+
f"[bold medium_purple]mockstack[/bold medium_purple] ready to roll. version: [medium_purple]{version}[/medium_purple]. "
|
|
17
20
|
f"debug: [medium_purple]{settings.debug}[/medium_purple]. "
|
|
18
21
|
f"strategy: [medium_purple]{settings.strategy}[/medium_purple]. ",
|
|
19
22
|
extra=extra,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: mockstack
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.7.1
|
|
4
4
|
Summary: An API mocking workhorse
|
|
5
5
|
Author-email: Adam Ever-Hadani <mockstack.contact@gmail.com>
|
|
6
6
|
License-Expression: MIT
|
|
@@ -37,6 +37,8 @@ Dynamic: license-file
|
|
|
37
37
|
[](https://github.com/adamhadani/mockstack/actions/workflows/ci.yml)
|
|
38
38
|
[](https://github.com/adamhadani/mockstack/blob/main/LICENSE)
|
|
39
39
|
[](https://pypi.org/project/mockstack/)
|
|
40
|
+
[](https://pypi.org/project/mockstack/)
|
|
41
|
+
|
|
40
42
|
|
|
41
43
|
An API mocking workhorse :racehorse:
|
|
42
44
|
|
|
@@ -48,21 +50,21 @@ Use mockstack for:
|
|
|
48
50
|
|
|
49
51
|
* **Integration Testing** :ok_hand:. Creating a consistent environment for running integration tests on a single component, using fixture responses.
|
|
50
52
|
|
|
51
|
-
* **LLM-powered Workflows** :alien:. Speeding up development of LLM-based workflows and tools for use with frameworks such as [LangChain](https://python.langchain.com/docs/introduction/), [LangGraph](https://www.langchain.com/langgraph) and others. When developing LLM-driven execution graphs, you often want to have a consistent response from a tool while you're tuning prompts or debugging other aspects of a particular trace.
|
|
53
|
+
* **LLM-powered Workflows** :alien:. Speeding up development of LLM-based workflows and tools for use with frameworks such as [LangChain](https://python.langchain.com/docs/introduction/), [LangGraph](https://www.langchain.com/langgraph) and others. When developing LLM-driven execution graphs, you often want to have a consistent response from a tool while you're tuning prompts or debugging other aspects of a particular trace. **mockstack** can give you a solid foundation for this.
|
|
52
54
|
|
|
53
|
-
* **Chaos Engineering** :boom:. mockstack can simulate various real-world runtime error scenarios such as timeouts, http error codes, and invalid response payloads. This can be a great way to do some upfront
|
|
55
|
+
* **Chaos Engineering** :boom:. mockstack can simulate various real-world runtime error scenarios such as timeouts, http error codes, and invalid response payloads. This can be a great way to do some upfront [Chaos Monkey](https://github.com/Netflix/chaosmonkey) type of testing on software components.
|
|
54
56
|
|
|
55
57
|
Highlights include:
|
|
56
58
|
|
|
57
|
-
* Multiple strategies for handling requests such as
|
|
58
|
-
* Observability via OpenTelemetry integration. Get detailed traces of your sessions instantly reported to backends such as Grafana, Jaeger, Zipkin, etc. :eyes:
|
|
59
|
-
* Configurability via
|
|
59
|
+
* Multiple strategies for handling requests such as [Jinja](https://jinja.palletsprojects.com/en/stable/) template files with intelligent URL request-to-template routing, proxy strategy, and mixed strategies. :game_die:
|
|
60
|
+
* Observability via [OpenTelemetry](https://opentelemetry.io/) integration. Get detailed traces of your sessions instantly reported to backends such as [Grafana](https://grafana.com/), [Jaeger](https://www.jaegertracing.io/), [Zipkin](https://zipkin.io/), etc. :eyes:
|
|
61
|
+
* Configurability via [pydantic-settings](https://docs.pydantic.dev/latest/concepts/pydantic_settings/) supports customizing behaviour via environment variables and a `.env` file. :flags:
|
|
60
62
|
* Comprehensive unit-tests, linting and formatting coverage as well as vulnerabilities and security scanning with full CI automation to ensure stability and a high-quality codebase for production-grade use. :+1:
|
|
61
63
|
|
|
62
64
|
|
|
63
65
|
## Installation
|
|
64
66
|
|
|
65
|
-
Install using [uv](https://docs.astral.sh/uv/). This package conforms the concept of a [tool](https://docs.astral.sh/uv/concepts/tools/) and hence can simply install / run with
|
|
67
|
+
Install using [uv](https://docs.astral.sh/uv/). This package conforms the concept of a [tool](https://docs.astral.sh/uv/concepts/tools/) and hence can simply install / run with [uvx](https://docs.astral.sh/uv/guides/tools/):
|
|
66
68
|
|
|
67
69
|
uvx mockstack --help
|
|
68
70
|
|
|
@@ -1,15 +1,19 @@
|
|
|
1
|
+
.dockerignore
|
|
1
2
|
.env.example
|
|
2
3
|
.gitignore
|
|
3
4
|
.pre-commit-config.yaml
|
|
4
5
|
CODE_OF_CONDUCT.md
|
|
6
|
+
Dockerfile
|
|
5
7
|
LICENSE
|
|
6
8
|
README.md
|
|
7
9
|
SECURITY.md
|
|
10
|
+
docker-entrypoint.sh
|
|
8
11
|
mkdocs.yml
|
|
9
12
|
pyproject.toml
|
|
10
13
|
uv.lock
|
|
11
14
|
.github/workflows/ci.yml
|
|
12
15
|
.github/workflows/publish-docs.yml
|
|
16
|
+
.github/workflows/publish-to-dockerhub.yml
|
|
13
17
|
.github/workflows/publish-to-pypi.yml
|
|
14
18
|
docs/configuration.md
|
|
15
19
|
docs/assets/favicon.ico
|
|
@@ -25,6 +29,7 @@ examples/filefixtures-with-templates/templates/servicename2-api-v2-user.533ec889
|
|
|
25
29
|
examples/llm/README.md
|
|
26
30
|
examples/llm/mockstack-langchain-example.ipynb
|
|
27
31
|
examples/llm/templates/openai-v1-chat-completions.j2
|
|
32
|
+
examples/llm/templates/openai-v1-deployments-gpt-4o-chat-completions.j2
|
|
28
33
|
examples/proxyrules-with-rules-file/.env.example
|
|
29
34
|
examples/proxyrules-with-rules-file/README.md
|
|
30
35
|
examples/proxyrules-with-rules-file/rules.yml
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|