To solve the given optimization problem, we first need to convert the natural language description into a symbolic representation. Let's denote:

- $x_1$ as the number of small cabinets to buy,
- $x_2$ as the number of large cabinets to buy.

The objective is to maximize the total number of seasonings and spices that can be stored, which can be represented by the objective function: $30x_1 + 40x_2$.

The constraints are:
1. Space constraint: $4x_1 + 8x_2 \leq 200$ (since each small cabinet takes 4 sq ft and each large cabinet takes 8 sq ft, and there are 200 sq ft available).
2. Budget constraint: $70x_1 + 120x_2 \leq 1400$ (since a small cabinet costs $70 and a large cabinet costs $120, with a budget of $1400).
3. Non-negativity constraints: $x_1 \geq 0$, $x_2 \geq 0$ (since we cannot buy a negative number of cabinets).

Therefore, the symbolic representation of the problem is:
```json
{
    'sym_variables': [('x1', 'number of small cabinets'), ('x2', 'number of large cabinets')],
    'objective_function': '30*x1 + 40*x2',
    'constraints': ['4*x1 + 8*x2 <= 200', '70*x1 + 120*x2 <= 1400', 'x1 >= 0', 'x2 >= 0']
}
```

To solve this problem using Gurobi in Python, we will use the following code:
```python
from gurobipy import *

# Create a new model
m = Model("Cabinet_Optimization")

# Define variables
x1 = m.addVar(vtype=GRB.INTEGER, name="small_cabinets")
x2 = m.addVar(vtype=GRB.INTEGER, name="large_cabinets")

# Set the objective function
m.setObjective(30*x1 + 40*x2, GRB.MAXIMIZE)

# Add constraints
m.addConstr(4*x1 + 8*x2 <= 200, "space_constraint")
m.addConstr(70*x1 + 120*x2 <= 1400, "budget_constraint")

# Optimize the model
m.optimize()

# Print the results
if m.status == GRB.OPTIMAL:
    print("Optimal solution found:")
    print(f"Number of small cabinets: {x1.x}")
    print(f"Number of large cabinets: {x2.x}")
    print(f"Total seasonings and spices that can be stored: {30*x1.x + 40*x2.x}")
else:
    print("No optimal solution found")
```